Vodafone K3770

24 Jun 2013

Hello!

I've tried a few times to get my K3772 (there's no "z" at the end in any of the docs, and I'm wondering if that might be the problem?) to work - without success.

I'll confess to being something of a newb to this, and would really appreciate any tips for debugging.

First - how the blazes do you turn the [DBG] messages on?

Second - Is there a super verbose test harness / version of the library?

25 Jun 2013

Hi,

to enable more verbose debug logging you'll have to delve into the library. For exampel to see more output on the AT commands have a look at VodafoneUSBModem/at/ATCommandsInterface.cpp It has a line:

#define __DEBUG__  2 //ERR+WARN

You can change the 2 for a 3 or a 4 to increase the verbosity of the messages. Another place to look for SMS delivery/reception is VodafoneUSBModem/sms/SMSInterface.cpp

It looks like pretty much all the modules within the library have this feature and just targetting a specific area would help rather than enabling everything at once as this may produce an information overload.

I've used these before when debugging my code.

Hope this helps.

Andrew

27 Jun 2013

You can also set the baud rate and line ending for debugging by putting this in the beginning of your main function:

DBG_INIT();
DBG_SET_SPEED(115200);
DBG_SET_NEWLINE("\r\n");

Changing accordingly.

If you want to use Donatien's debug functions in your own code, you need to define _ _MODULE_ _ in the top of the file you want to debug, like this for example for main.cpp:

#define __DEBUG__ 4 //Maximum verbosity
#ifndef __MODULE__
#define __MODULE__ "main.cpp"
#endif

Noting that I've also defined _ _DEBUG_ _ to turn it on. You also have to call DBG_INIT() too. The different macros you can use for debugging are defined in dbg.h.

There are 4 levels of debugging:

#if __DEBUG__ >= 1
#define ERR(...) do{ debug(1, __MODULE__, __LINE__, __VA_ARGS__); }while(0)
#else
#define ERR(...) do{ }while(0)
#endif

#if __DEBUG__ >= 2
#define WARN(...) do{ debug(2, __MODULE__, __LINE__, __VA_ARGS__); }while(0)
#else
#define WARN(...) do{ }while(0)
#endif

#if __DEBUG__ >= 3
#define INFO(...) do{ debug(3, __MODULE__, __LINE__, __VA_ARGS__); }while(0)
#define CHECK(ret) do{ if(ret){ debug_error(__MODULE__, __LINE__, ret); } }while(0)
#else
#define INFO(...) do{ }while(0)
#define CHECK(ret) do{ }while(0)
#endif

#if __DEBUG__ >= 4
#define DBG(...) do{ debug(4, __MODULE__, __LINE__, __VA_ARGS__); }while(0)
#define DBGX(...) do{ debug_exact(__VA_ARGS__); }while(0)
#else
#define DBG(...) do{ }while(0)
#define DBGX(...) do{ }while(0)
#endif

Note that the difference between DBG and DBGX is that the latter does not append a newline. All the other macros (DBG,INFO,ERR, and WARN) do append a newline, so there is no need to manually append a newline when you use them. There also appears to be a CHECK macro to check for assertions, which I've never used myself.

As Andrew points out, to enable debug output from the cellular library, you need to set _ _DEBUG_ _ to a value between 1 and 4 depending on the level of verbosity you want, and you need to do this per file. For example, if you want debug output for SMS then you need to set _ _DEBUG_ _ in the top of SMSInterface.cpp.

Ashley

27 Jun 2013

I've just noticed, that K3772 support hasn't been pushed downstream yet into the official library.

This bleeding edge version should work for now:

http://mbed.org/users/donatien/code/VodafoneUSBModem_bleedingedge/

Ashley

27 Jun 2013

@Ashley - Thank you very much! I'm getting a permissions error when I try to get the bleedingedge lib... do I need to contact the author for permissions

27 Jun 2013

OK, I've just updated the official library, as we've been using these changes for a while now without issue.

Can you try updating this and trying again with the K3772?

Ashley

27 Jun 2013

Will try again this eve and report back. Thanks! [EDIT] Ok, My curiosity got the better of me and I updated the library in my version of VodafoneUSBModemHTTPClientTest and bingo - It worked a treat!

Awesome. (You guys, that is, not me.)

28 Jun 2013

Hi all,

I would like to use the VodafoneUSBModem library over 4G/LTE networks. Would it works for the Vodafone K5005/Huawei E398 (4G/LTE) USB modem?

Thank you, Michel

20 Aug 2013

Hi. I have also checked this modem personally in the UK, Kenya and Rwanda. It works with successful 3G connections. I'm using an unlocked K3770. Just thought I'd share this.

Piotr Sladek wrote:

Hi, I have checked this modem personally on the USA area. So I can confirm it working fine (EDGE only, 3G is supported only on EUROPE,Africa, Oceania).

20 Sep 2013

Finally I found the bug that Andy was having above. It's pretty obvious now, but then these things usually are.

In a nutshell: Carriage Return (0x0D) is not parsed correctly in incoming SMS messages.

The reason for this is that the AT parser (not implemented by me), splits everything up into lines by looking for the sequence CRLF (0x0D 0x0A) at the beginning and end of messages. This might seem unreasonable, but it isn't, as every AT response always begins with CRLF and always ends with CRLF (except an SMS send prompt). So to write a parser this way, isn't entirely unreasonable. The problem in this case however is that when you read an SMS using AT+CMGR=ID, you do not want the parser to split the SMS body at the first CR it finds, otherwise the parser will be in an inconsistent state, as it will expect a response code to follow.

The workaround for this is a little tricky, as the AT parser is built around this way of splitting incoming lines, so I'll probably have to temporarily hand control of the (virtual) serial interface from the AT parser to the SMSInterface to deal with this special case. I will work on a fix for this and update you when it is done.

Apologies for any inconvenience. The test suite now has a use case to check for this.

P.S. One of the reasons this wasn't spotted earlier is because most cellphones use only LF (0x0A) for a newline, in which case the message is received as one line. So although we had sent many multi-line messages to the library, the use case was only triggered in certain cases. If you look back above at Andy's problem, you can actually see in the output, that the line is split at his CR character...

03 Oct 2013

hi all, is this project (interface between vodafone modem 3g to mbed) can be applied in arduino? my final project is make an interface between arduino and usb modem 3g. i need some help. thanks

08 Oct 2013

Hi Adli,

At present the code does not work on Arduino, not even the ARM based Arduino (the only one with a proper USB host). The differences and issues are too numerous to list. Whilst in theory you could reuse some of the code and there are no license restrictions, in practice it would be quite an involved task.

Shoot me for pointing out the obvious, but it seems there is an easy solution: why don't you just use an mbed for the task instead?

Ashley

29 Mar 2014

Hi all

Could this library work with k7765 or e220 or e1550? did any one had succeses with some of them?

01 Apr 2014

The library should be able to work with pretty much any dongle but you'd need to make modifications to detect the VID and PID of the product and then setup the correct number of virtual serial channels accordingly.

Just to let everyone know, a bugfix for the SMS newline bug will be pushed back into the mainline soon (by using UCS2 charset instead). And we've got some extra functionality coming :D I'll keep you posted.

03 Apr 2014

Is it posible to have a quick guide on how to modify or a list things to do to try others dongles. would the library work on Nucleo L401 board because it support USB Host as much i know or it LPC1768 dependent?

Thanks.

05 Apr 2014

I got Vodafone 3g modem from our local store (Vodafone Qatar) and I'm having troubles running it with mbed. Can we use the library outside UK? also, can we use it on other vodafone models (k3806)?

09 Apr 2014

Abdessamad El Abbassi wrote:

Is it posible to have a quick guide on how to modify or a list things to do to try others dongles. would the library work on Nucleo L401 board because it support USB Host as much i know or it LPC1768 dependent?

The first point is very similar to what SDP Streetlight is asking, and it has been asked a lot. I really want to find the time to do this properly. Roughly, what needs to be done is as follows:

  1. Edit this file [http://mbed.org/users/mbed_official/code/USBHostWANDongle/file/980fe31c14f7/USB3GModule/WANDongleInitializer.cpp] and create a clone of one of the classes you see for an existing modem, such as K3770
  2. Change the VID and PID in the getMSDVid, getMSDPid of your new class to match the VID and PID of the dongle when it's in mass storage mode
  3. Change the VID and PID in the getSerialVid, getSerialPid functions of your new class to match the VID and PID of the dongle when it's been flipped into ACM mode
  4. Edit the vodafone_XXX_switch_packet to encode the flip string that is required to flip the dongle from MSD to ACM mode.
  5. Change the number of endpoints to fetch in the setVidPid method of your new class
  6. Add your initialiser to the list defined in: WANDongleInitializer::getInitializers
  7. Add your new dongle type to the header file [http://mbed.org/users/mbed_official/code/USBHostWANDongle/file/980fe31c14f7/USB3GModule/WANDongleInitializer.h] in the ENUM WAN_DONGLE_TYPE
  8. Add any custom initialisation code to: VodafoneUSBModem::init() [http://mbed.org/users/mbed_official/code/VodafoneUSBModem/file/c5d90f929f8d/VodafoneUSBModem.cpp]

In a lot of cases, the dongle will appear in ACM mode immediately and you can set the VID and PID to be the same and ignore the flip string stuff.

There are a few edge cases where you need to know how many virtual serial ports the device is enumerating and which one of those is the one to use, and then set this in the getEp function of your new class. This is what makes it a bit tricky, in that someone needs to bother to sit down and write a tutorial on how to systematically get all of the required information. Or even a script that assists in this.

I'm thinking of refactoring the initialisation code, so that the classes are separated out and can be enabled/disabled via defines. This would make it clearer what is going on and make it easier to trim the code. But again, time.

It's probably also worth noting here that the mbed team did some work on a fork of this library to get the Ublox C027 series working, and they made some refactorisations which I believe were aimed at making the library more generic. See for example: [https://mbed.org/users/mbed_official/code/CellularUSBModem/]. I'm not sure where they are planning to take this.

What I can say, is that we are adding more features to our branch of the code and will be pushing them soon.

Hope this helps a little bit at least.

Ashley

09 Apr 2014

SDP Streetlight wrote:

I got Vodafone 3g modem from our local store (Vodafone Qatar) and I'm having troubles running it with mbed. Can we use the library outside UK? also, can we use it on other vodafone models (k3806)?

You can certainly use the library outside the UK as there is nothing inherent in it that makes it specific to the UK. (Sprint made a fork of the library to use with their dongles in the USA for example). But that fork has nothing to do with the country, only the dongle. The library should work with pretty much any USB dongle if you can get someone to make the modifications I talk of above.

09 Apr 2014

Thanks a lot Ashely, but what would number do we change the endpoint to?

16 Apr 2014

Thanks a lot Ashely, it's very helpful to get started i had already ordered a k3770 dongle, but now i only own a Nucleo F401 mbed microcontroller and the there is no USB Host support for now , i'm wondering if someone could help !!

30 Apr 2014

SDP Streetlight wrote:

Thanks a lot Ashely, but what would number do we change the endpoint to?

The way that the library selects the serial ports works like this:

1. The total number of endpoints enumerated is controlled by m_endpointsToFetch, this is usually the number of virtual serial ports multiplied by 2. Most USB virtual serial ports have 3 endpoints, but only two of these are BULK endpoints and the other is an INTERRUPT endpoint. We only need the BULK endpoints. Usually there will be 2 virtual serial ports so set the number of endpoints to 4.

2. The endpoints will be taken from the first interfaces that have BULK endpoints (as indicated by the function useEndpoint). You need to choose which interfaces are selected by altering the parseInterface function for your modem. For the K3770 it looks like this:

bool VodafoneK3770Initializer::parseInterface(uint8_t intf_nb, uint8_t intf_class, uint8_t intf_subclass, uint8_t intf_protocol) //Must return true if the interface should be parsed
{
  if( m_hasSwitched )
  {
    if( intf_class == 0xFF )
    {
      if( (m_currentSerialIntf == 0) || (m_currentSerialIntf == 4) )
      {
        m_currentSerialIntf++;
        return true;
      }
      m_currentSerialIntf++;
    }
  }
  else
  {
    if( (intf_nb == 0) && (intf_class == MSD_CLASS) )
    {
      return true;
    }
  }
  return false;
}

Which means it selects interfaces the first (0) and fifth (4) interfaces that have interface class 0xFF.

This is a little bit esoteric, but you can construct this parseInterface function to explicitly choose an interface. You could also parse all interfaces by always returning true, and then select out the ports later, but it makes more sense just to enumerate those interfaces that correspond to the serial ports.

How do you know which interfaces are the virtual serial ports? Well this is where you need to look at the device on your OS (after flipping it from MSD mode), and work out which ones are the virtual serial ports. Or you could just experiment a bit with the code until you find them.

3. The last thing you need to do is have an appropriate getEp function, looking at the K3770 again:

USBEndpoint* VodafoneK3770Initializer::getEp(USBDeviceConnected* pDev, int serialPortNumber, bool tx)
{
  return pDev->getEndpoint(serialPortNumber, BULK_ENDPOINT, tx?OUT:IN, 0);
}

It just returns the serial ports in the order they were found, so serialPortNumber 0 will return the first interface selected as true by parseInterface.

You need to make sure that the first serial port returned, is the serial port that allows AT commands. On modems that have dual serial ports, some reserve one exclusively for the PPP connection and do not allow you to send the full command set to both ports, on other modems, both ports behave the same. This is a modem specific thing. For example, look at the K3772Z:

USBEndpoint* VodafoneK3772ZInitializer::getEp(USBDeviceConnected* pDev, int serialPortNumber, bool tx)
{
  return pDev->getEndpoint((serialPortNumber==1)?0:1, BULK_ENDPOINT, tx?OUT:IN, 0);
}

In this case, the second serial port (as enumerated) was the one that AT commands had to be sent down, and the first serial port is the one used for PPP. So in this case we just swap around the return order. On other modems (I'm just speculating here) with more serial ports, you might need to return the 3rd serial port and you'd have to change the code accordingly. If you look at most of the examples, most of the time you just need to copy the K3770 example.

BTW, I didn't write this code structure, so I've reversed engineered all this information for you. I did add the K3773 modem by using this information however.

I wanted to write a program that would automatically test each interface and find out automatically what the settings could be, but didn't have time. I also wanted to write a tutorial on how to get the relevant information from Linux or FreeBSD USB interrogation tools, and got somewhere but didn't have time to complete it.

The problem is, many of these vendors use the interface class 0xFF which means "vendor specific" instead of using CDC or ACM mode so there isn't a sure-fire way of determining which are the virtual serial ports other than testing them. Or if they enumerate successfully on the OS you are using, you can try and work out to which interfaces /dev/ttyU0 or whatever corresponds and do it like that.

If I find the time, I'll try and put everything above into a more coherent tutorial. Otherwise you can always contact me privately for consulting services from my company.

Ashley

01 May 2014

Abdessamad El Abbassi wrote:

Thanks a lot Ashely, it's very helpful to get started i had already ordered a k3770 dongle, but now i only own a Nucleo F401 mbed microcontroller and the there is no USB Host support for now , i'm wondering if someone could help !!

The controllers on the F401 are listed as OTG, which means they should be able to switch between device and host mode. Is this supported by the mbed USB library? You could try it.

Ashley

12 May 2014

Ashley West wrote:

The controllers on the F401 are listed as OTG, which means they should be able to switch between device and host mode. Is this supported by the mbed USB library? You could try it.

Ashley

Yes it does support USB Host but mbed USBHost library doesn't have support for it, i'll try to port it and see how dificult is to make it work.

12 Aug 2014

I found this thread a bit late. HAve you made any progress on STM32 Host ? and even 3g modem ?

15 Aug 2014

Hi Daniel, I tried to make 3g modem driver work with ST usb host library with no luck. However i'm still interested in making the 3g modem to work with stm32F4. recently i found a working mbed USB host library here

Import libraryF401RE-USBHost

Simple USBHost library for Nucleo F446RE/F411RE/F401RE FRDM-KL46Z/KL25Z/F64F LPC4088/LPC1768

, i haven't test it yet so hopefully it will make it easy to work with the already existing 3g modem drivers. I don't have much time to work on it thats why i moved to an lpc1768 based board. i'll try to test it these days and see what happens.

22 Aug 2014

Hello Abdessamad, In fact I realized that it's a post for LPC1768 thread for 3G Modem (and I have seen/read before this thread). I was more interested to STM32 usb host library like you have sent to me.

Regarding this 3G Modem Library, this does not compile anymore ! I have tried several times those days. Looking on library revisions it seems that Ashley Mills it's working on them ...

I will try as well to compile it for STM32..

BR Daniel

22 Aug 2014

Hi Daniel,

The library still compile for LPC1768, try latest Ashley SMS example

Import programVodafoneSMSBasics

Shows how to send and receive SMS messages using a Vodafone USB dongle.

I tested it yesterday on a custom LPC1768 board and it works fine with K3770 and K772-Z , also the HTTP Client code worked with it.

The vodafone USB Modem library include only USB Host library for LPC1768, you need to add USB Host support for STM32F4, you may want to try with Norimasa Okamoto USB Host library.

Maybe someone from Vodafone USB Modem library developers could tell us which changes has been made to the USB Host library and help to make it work on STM32F4 plataform. I will be gratefull.

Abdessamad.

26 May 2015

Hi There

Hopefully this thread is still actice.

I am using the Huawei E353 Modem (from "DREI") for my purpose and I added the modem as new instance. It is working. Kind of. The thing is the strange behavior of the USB Donge.

When transmitting the bulk message for the usb mode switch the new device connects BEFORE the old device disconnects. See that debug output:

debug_output.txt

[DBG] Module USBHost.cpp - Line 645: device enumerated!!!!<\n>
[DBG] Module WANDongle.cpp - Line 81: Device has VID:12d1 PID:1446<\n>
[DBG] Module WANDongle.cpp - Line 85: m_pInitializer=10000640<\n>
[DBG] Module WANDongle.cpp - Line 86: m_pInitializer->getSerialVid()=12d1<\n>
[DBG] Module WANDongle.cpp - Line 87: m_pInitializer->getSerialPid()=1506<\n>
[DBG] Module WANDongle.cpp - Line 116: Dongle detected in MSD mode<\n>
[DBG] Module WANDongleInitializer.cpp - Line 717: Drei E353 MSD descriptor found on device 1000394c, intf 0, will now try to switch into serial mode<\n>
[DBG] Module USBHost.cpp - Line 459: Next td = 20080170<\n>
[DBG] Module USBHost.cpp - Line 475: Buf=268435773, len=31<\n>
[DBG] Module USBHost.cpp - Line 480: Now do queue transfer on ep 1000381c<\n>
[DBG] Module USBHost.cpp - Line 484: Enable list if needed<\n>
[DBG] Module USBHost.cpp - Line 499: Wait for HC to process TD<\n>
[DBG] Module USBHost.cpp - Line 776: !!!!!!!!!!!!! bulkwrite finished<\n>
[DBG] Module WANDongle.cpp - Line 120: Switched OK<\n>
[DBG] Module USBHALHost.cpp - Line 323: Locked<\n>
[WARN] Module USBHALHost.cpp - Line 325: isr 00000006 [EN 80000042]<\n>
[DBG] Module USBHost.cpp - Line 104: td=20080170 FOUND ed: 20080110<\n>
[DBG] Module USBHost.cpp - Line 112: !1000381c<\n>
[DBG] Module USBEndpoint.cpp - Line 202: current:20080180, next:20080170<\n>
[DBG] Module USBHALHost.cpp - Line 392: Unlocked<\n>
[DBG] Module USBHALHost.cpp - Line 323: Locked<\n>
[WARN] Module USBHALHost.cpp - Line 325: isr 00000044 [EN 80000042]<\n>
[WARN] Module USBHALHost.cpp - Line 332: Port status 00030101<\n>
[WARN] Module USBHALHost.cpp - Line 351: Device connected!!<\n>
[DBG] Module USBHALHost.cpp - Line 392: Unlocked<\n>
[DBG] Module VodafoneUSBModem.cpp - Line 527: Trying to connect the dongle<\n>
[DBG] Module WANDongle.cpp - Line 48: Trying to connect device<\n>
[DBG] Module WANDongle.cpp - Line 64: Found one device reset it<\n>
[DBG] Module VodafoneUSBModem.cpp - Line 527: Trying to connect the dongle<\n>
[DBG] Module WANDongle.cpp - Line 48: Trying to connect device<\n>
[DBG] Module WANDongle.cpp - Line 64: Found one device reset it<\n>
[DBG] Module VodafoneUSBModem.cpp - Line 527: Trying to connect the dongle<\n>
[DBG] Module WANDongle.cpp - Line 48: Trying to connect device<\n>
[DBG] Module WANDongle.cpp - Line 64: Found one device reset it<\n>
[DBG] Module USBHALHost.cpp - Line 323: Locked<\n>
[WARN] Module USBHALHost.cpp - Line 325: isr 00000044 [EN 80000042]<\n>
[WARN] Module USBHALHost.cpp - Line 332: Port status 00030100<\n>
[WARN] Module USBHALHost.cpp - Line 358: Device disconnected!!<\n>
[DBG] Module VodafoneUSBModem.cpp - Line 527: Trying to connect the dongle<\n>
[DBG] Module WANDongle.cpp - Line 48: Trying to connect device<\n>
[WARN] Module USBHost.cpp - Line 189: device disconnected: 1000394c<\n>
[DBG] Module USBHost.cpp - Line 209: FREE INTF 0, 1000394c, nb_endpot: 1<\n>
[DBG] Module USBHost.cpp - Line 212: Freeing USBEndpoint<\n>
[DBG] Module USBHost.cpp - Line 215: Dequeueing USBEndpoint<\n>
[DBG] Module USBHost.cpp - Line 241: want to unqueue ep: 20080110<\n>
[DBG] Module USBHost.cpp - Line 245: USBEndpoint unqueued: 20080110<\n>
[DBG] Module USBHost.cpp - Line 218: Freeing first transfer descriptor<\n>
[DBG] Module USBHost.cpp - Line 220: Freeing second transfer descriptor<\n>
[DBG] Module USBHost.cpp - Line 223: Freeing USBEndpoint descriptor<\n>
[DBG] Module USBHost.cpp - Line 230: Disconnecting device<\n>
[DBG] Module USBHost.cpp - Line 232: Device disconnected<\n>
[DBG] Module USBHALHost.cpp - Line 392: Unlocked<\n>

See how after the switch the device is found and connected. Then of course the old MSD device gets disconnected and all the handles are dropped. Thus making it not possible to connect to the modem mode device later.

So I was thinking if i should delete the using USBHost library and try to include the recent one of the mbed crew. But the source differ so much, I just wanted to ask if that is ok before doing the wrong thing.

Thanks.

You need to log in to post a reply