This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Firmware bugs in mDNS on latest cc3000 firmware

Other Parts Discussed in Thread: MSP430FR5739, TM4C123GH6PM

Hello,

I just started using the mDNS command and I noticed a few issues right away.  First off, I am using the latest firmware 1.11.  I have a lot of experience with mDNS, having written my own implementation previously.  So here are my issues:  

1. Local name is hardcoded to "target.local" instead of what the user specified.  So, for instance, I named my cc3000 "helloworld" with the HCI_CMND_MDNS_ADVERTISE command, but the mDNS response sets that name to "target.local".  So, instead of having a name that resolves to "helloworld.local", it resolves to target.local.  So, now it responds to ping at target.local:  

And here is the problem shown in wireshark:  

Also, here is another user asking for a change to TTL, but if you look, his wireshark information also reports "target.local"  : http://e2e.ti.com/support/low_power_rf/f/851/t/262801.aspx

Because of this all cc3000 devices on the local network will have the same conflicting name "target.local" -- very bad.  And because of this, local mDNS name resolution is quite broken.  

2. The mDNS "query response" is supposed to be sent in response to a query from another device on the local network.  So when there is an mDNS Query for the name helloworld (or whatever), the cc3000 is supposed to be listening and immediately send the "query response", but it seems that it is not listening to the multicast mdns port.  It should be continuously listening for queries and respond (when mdns is enabled of course).  In the above wireshark trace, it appears to work, but that is only because I am actually calling HCI_CMND_MDNS_ADVERTISE every 10 seconds.  This means that responses can take as much as 10 seconds just for name resolution, which is very bad.  The mDNS advertiser, when enabled, MUST respond to queries.  The cc3000 must continuously listen for the queries when mDNS is enabled.  

My recommendation would be to add a new value to the "mdnsEnabled" variable so that 0 = disabled, 1 = enabled, 2 = enabled and listening.  That way, it is not a breaking change.  

3.  I don't know if this is a wireshark parse issue or a bug in the mDNS packet, but the first letter in the service record is missing.  

4. Finally, this is more of a suggestion than anything else.  LLMNR is nearly identical to mDNS, but that is what all Windows Vista, 7, 8 versions all use by default.  The cc3000 could EASILY respond to both messages, the responses are nearly Identical for the local name (A Record).  Windows is still the most widely used OS in the world and it REALLY should work out of the box.  The cc3000 should implement LLMNR.  

Thanks.  

  • I'm sad that this has gotten no response from TI - they're usually pretty good at at least acknowledging clearly competent technical questions.

    I was going to ask a nearly identical question - having found much the same things myself.

    For me the big issues are:

    • it announces an A record for itself using the name "target.local" rather than the name you gave the device.
    • it doesn't respond to mDNS queries.
    • it occasionally seems to fail to send an mDNS message when you use HCI_CMND_MDNS_ADVERTISE.

    Like Valkyrie-MT I've been recording the traffic on the mDNS multicast group. Rather than wireshark I actually wrote a tiny Java application to do this and used dnsjava to parse and display the messages so that I had complete control over things.

    Valkyrie-MT reports that he saw the first letter truncated from the service name in wireshark - I suspect this may be a wireshark issue as I did not see anything similar.

    Not responding to mDNS queries is a serious issue - are developers expected to handle this themselves? I.e. TI is giving them the choice of:

    1. using up resources to explicitly listen for queries and calling HCI_CMND_MDNS_ADVERTISE in response (or hand craft responses to simple hostname or reverse IP queries that aren't covered by HCI_CMND_MDNS_ADVERTISE), or
    2. saving on resources but not playing nice in the mDNS world.

    If that's the case can someone from TI please confirm it?

    Even if that's so I still think it's a bug that the CC3000 calls itself "target.local" in the A record, and it's definitely a bug that it sometimes fails to produce any mDNS message at all when calling HCI_CMND_MDNS_ADVERTISE.

    The CC3000 must use CSMA/CA so collisions shouldn't be the explanation for these missing messages, although maybe CSMA/CA isn't used when sending such small one off UDP packets? Even then my network is very lightly loaded so even given the potential for collisions I wouldn't expect to see this issue as often as I do.

    If the CC3000 announces itself via DNS-SD/mDNS then I really think it should handle queries too as part of its firmware and should respond properly to _device_info queries, and given that it advertises an A record I think it should also respond properly to basic hostname and reverse IP queries.

    At the moment the one off announcement (resulting from a call to HCI_CMND_MDNS_ADVERTISE) soon expires from the caches of any other clients on the network (and never appears in the caches of clients that didn't happen to be active at the time the HCI_CMND_MDNS_ADVERTISE call was made). And the "target.local" name is just bizarre.

  • Hi George,

    Yes I can confirm that the CC3000 does not reply to mDNS queries. Also SRV, TXT and PTR types are user defined. The A type is not. There's only so much functionaility that can fit into the chip, so we have to pick and choose what to implement.

    Regards,
    Aaron

  • Thanks for confirming that Aaron, but I am quite confident that we knew that the CC3000 does not reply to mDNS queries.  The problem here is that the mDNS spec requires that it does respond along with a variety of other requirements.  Including (RFC6762 - http://tools.ietf.org/html/rfc6762):

    • A Multicast DNS responder MUST NOT send announcements in the absence of information that its network connectivity may have changed in some relevant way.  In particular, a Multicast DNS responder MUST NOT send regular periodic announcements as a matter of course.
    • Whenever a Multicast DNS responder receives any Multicast DNS response (solicited or otherwise) containing a conflicting resource record, the conflict MUST be resolved as described in Section 9,    "Conflict Resolution".

    So a few points here. 

    1. By making all devices have the same "target.local" name, you are in violation of the specifications for mDNS.  You cannot hardcode the name. 
    2. A string substitution (which you are already doing for the service answer) will not increase the size of the firmware on the chip.  You already have a variable for the name, just reuse it in the A Record answer.  It's an absolutely trivial change. 
    3. By not properly supporting local name resolution you are preventing perhaps the biggest use case, which is to have multiple devices in the home with a cc3000 chip to connect them.  If they are all named target.local, you would never be able to host a webserver that is independently addressable with a distinct name. 
    4. By advertising this name, you are actually creating a name conflict without having implemented the required name conflict resolution handler.   

    A canned Multicast UDP packet, sent only on command, is NOT a valid mDNS (ZeroConf) implementation.  IMHO, you don't have to implement the entire RFC, but allowing the developer to set the name at least gives us a chance to avoid a name conflict. 

    If you need help understanding how to implement this, I am happy to help.  I have written a TCP/IP stack myself (mip.codeplex.com) with 3 tiers of local name resolution -- mDNS, LLMNR, and NetBIOS over TCP.  Embedded devices NEED proper name resolution. 

    Also, I recommend looking at the O'Reilly book "Zero Configuration Networking", see page 44. 

    Please try harder on this.  It's important for you and it's important for us. 

  • I agree with Valkyrie-MT on nearly everything he says - however I'm not going to be quite so insistent in how I look at this.

    I'm prepared to accept that the CC3000 only has so much room to implement functionality.

    My impression is that one could implement full mDNS functionality in the driver code (or user level code) rather than the CC3000 firmware.

    Doing so outside the firmware would force the user to make an explicit choice as to how important mDNS functionality is.

    For many users it may not be important enough that they are prepared to tie up some of the fairly scarce resources of the CC3000 in doing so, e.g. at the very least one of its limited number of sockets.

    However I do think that even if only a little bit of mDNS functionality is provided in firmware that functionality should at least make sense.

    I don't think the current choice to hardcode "target.local" in the A record while using the actual name of the device in the other records makes any sense.

    If you are going to include only a little bit of mDNS functionality in the firmware I think it would have made more sense to provide more basic functionality to help user's provide driver or user space support for full mDNS support, if they wanted it, rather than this unsatisfactory canned mDNS _device_info announcement (unsatisfactory for all the reasons outlined by Valkyrie-MT).

    If you're not going to enhance the mDNS functionality please at least fix the "target.local" issue which is just out and out odd.

    E.g. see this dig style dump of the DNS-SD announcement the CC3000 sends out. I've set the name of the CC3000 to "MyDeviceName" and this value appears in the PTR, TXT and in the name part of SRV records but bizarrely is not used in the A record or the rdata portion of the SRV record:

    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 0
    ;; flags: qr aa ; qd: 0 an: 5 au: 0 ad: 0
    ;; QUESTIONS:

    ;; ANSWERS:
    _device-info._udp.local.              4500 IN    PTR MyDeviceName._device-info._udp.local.
    _services._dns-sd._udp.local.         4500 IN    PTR _device-info._udp.local.
    MyDeviceName._device-info._udp.local. 4500 IN/cf TXT "dev=CC3000" "vendor=Texas-Instruments"
    MyDeviceName._device-info._udp.local. 4500 IN/cf SRV 0 0 1234 target.local.
    target.local.                         4500 IN/cf A 192.168.1.120

  • Hi guys,

    I understand your concerns, and I've asked our dev department to look into maybe changing the A record.

    Regards,

    Aaron

  • Hi Aaron,

    I would like to second that request, and also add my own difficulties using the mDNS watch program to discover the CC3000. It doesn't appear in the "Device Info" group at all, and I've confirmed with a Wireshark trace similar to what Valkyrie-MT posted that my advertisements are being sent.

    Thanks,

    Vishal

  • Thanks Aaron --

    I think fixing up the A record is a good first step. I appreciate you taking it up with the dev department.

    I think this is an easy fix - and can probably be quickly incorporated.

    I think adding query support, relative to this, is a bit more complex but still very simple.

    So it would be great if the dev team considered adding proper query support.

    Perhaps as an optional part of the driver logic - something that could be compiled out to free up resources for end users that don't want to accept the added cost of properly support mDNS.

    Now Vishal's issue - I think what you're seeing is also down to lack of query support.

    On Mac OS X you can query services (including the pseudo service _device_info) like so:

    $ dns-sd -B _device-info._udp

    If the Mac was active when the CC3000 connected to the network it will cache the mDNS records that the CC3000 announces.

    These records are marked with a TTL of 4500 seconds.

    The above dns-sd command will try to actively query for devices that advertise the _device-info._udp but will also return cached records, so for 75 minutes after the CC3000 announces itself this data will be returned by dns-sd.

    But if your tool (mDNS watch) relies only on active queries, which is a completely reasonable thing to do, and doesn't cache records then the CC3000 will never show up as, as discussed here in previous messages, it does not respond to queries.

    If I use avahi-browse, the Linux equivalent of dns-sd, then it never returns the CC3000 _device-info._udp information - so like your tool I presume it is relying on active querying and doesn't use cached data.

    Note: even the Mac will sometimes throw out records before the TTL period expires - e.g. if you put it to sleep, it will empty it's cache on waking.

    Valkyrie-MT - you seem to be a mDNS/DNS-SD expert, I don't have the O'Reilly book you mention above, and information about _device-info on the web seems to be scarce. What exactly does the "._udp" portion mean?

    _device-info is a pseudo service, i.e. there isn't actually anything that can be accessed, via UDP or TCP, so maybe it's irrelevant whether one uses "._udp" or "._tcp"? However any examples of _device-info I've found on the web always use "_device-info._tcp". The CC3000 seems to be the only thing advertising this service as "_device-info._udp" - is this of any significance?

  • Hi, 

    Regarding your questions:

     

    1. You're correct. We will modify  "target.local" to reflect the name as provided in the API. This will be done on our next release (V1.11.2 – no target date yet).
    2. "query response"  will not be implemented in this device. The user can implement this at host level though.
    3. Despite the similarity, we will not implement LLMNR in this device - This can be implemented from host level though.
    4. The CC3000 device shouldn't drop mDNS packets due to loaded network. This packet is treated as any other packet in the system. If packets are dropped from time to time, then it's a bug, and we should debug this issue.
    5. Just to clarify, we don't support the Bonjour protocol, but only a very narrow subset to advertise device information.

     Regards,

    Tomer

  • Tomer,

    Thanks for the response and the commitment to fix target.local.  Obviously, we are familiar with the constraints of embedded devices.  However, local name resolution is critical to having a functional consumer product, particularly, when the device does not have a user interface (something that becomes possible with SmartConfig).  

    In order to get local name resolution with a decent coverage of client devices, implementing both LLMNR and Bonjour (both are types of mDNS), would cover around 90% of client devices, but Bonjour alone, covers little more than Apple devices and the very newest Androids.  If I have to implement the listening for Bonjour and LLMNR, that would use 2 of the 4 sockets, and responding to LLMNR would require another without the built-in support.  Then listening on port 80 for a web server would require the 4th.  Then you are out of sockets with which to reply to web requests.  Also, service discovery is not really practical if you are not listening for the client probes.  

    I am open to alternatives (like 2 more sockets), but my vision is to use the cc3000 in consumer products where the user runs SmartConfig to join the network, then can go to any web browser on the local network and access the device's web page with a name, like http://lights.local or http://sprinklers.local.  Without local name resolution, you have to use an IP address (which could change periodically - DHCP), but how would a consumer ever even know what ip address was assigned?  Local name resolution is essential to the Internet of Things use-case.  It allows for a simple SmartConfig, then followed by just navigating to a name in your browser.

    I hope you'll consider the huge impact this will have on the product if you fully implement local name resolution on the cc3000.  

  • Hi Tomer,

    Thank you for the clear-cut responses. I, for one, do feel like I have been misled a bit by the marketing on this count:

    http://newscenter.ti.com/2013-01-03-Latest-TI-SimpleLink-Wi-Fi-CC3000-module-simplifies-home-network-setup-and-improves-user-experience

    "The CC3000 module now also supports service discovery applications on phones, tablets and PCs using Bonjour® zero-configuration networking technology, making it easier for consumers to quickly identify and manage networked devices."

    Additionally, the wiki page for CC3000 mDNS functionality states that for iOS, the applications "Discovery" and "mDNS Watch" can be used. I couldn't find the former, and the latter probably doesn't work for the reasons George surmised about the improper query behavior (though the screenshots indicate it does/did work under some conditions).

    That said, I am happy with a limited version of mDNS now that I know the facts, but I think the technical documentation (if not the marketing stuff) should be much clearer about how to properly use this mechanism for discovery. I know nothing about mDNS and didn't plan on getting intimate with it, since I thought the CC3000 would basically handle that on the device side, and there would be plenty of libraries to be use on the application side. It seems like I'll have to start getting familiar withit or come up with my own discovery mechanism. At the very least, a sample application would be a wonderful resource if the dev team has a chance to come up with one.

    Thanks,
    Vishal

  • Vishal,

    Thanks so much for reminding me that I originally selected the cc3000 based on those marketing documents stating that service Discovery and Bonjour were supported.  These documents are at best misleading and IMO wrong.  I would really like to see TI acknowledge that they are committed to fulfilling their marketing statements to have this work properly in a coming firmware release.  Service Discovery does not work unless the device is listening for the probes. 

    -Valkyrie-MT

  • Hi,

    You are correct. We  should have been more careful with the press release. We will summarize a new post that explains the mDNS capabilities, and apologize if the press release was not clear.

    Please note however, that on our wiki page, we do state that we support only one API to send mDNS packets to a multicast address. It is not stated the device can be in listen mode.

    The mDNS packet that we advertise is parsed correctly by:

    IOS - Discovery, mDNS Watch.

    Android - Bonjour Browser, ZeroConf Browser.

    If you use these applications, you will see the CC300 device displayed correctly. That was the meaning by saying:

    "The CC3000 module now also supports service discovery applications on phones, tablets and PCs using Bonjour..."

    We will not be able to support LLMNR and Bonjour internally in the device's firmware. Therefore, unfortunately  apart from fixing target.local, we will not be able to address your other concerns/requirements.

    To avoid further confustion, I will surely make sure to update the wiki page as well, and to clearly state what we actually support.


    Regards,

    Tomer


  • Thanks, Tomer! The wiki page is much clearer about the functionality but as a newcomer to device discovery, I wasn't sure how that function should be called in practice, and only after experimentation did I find that periodically calling it as long as you want advertising to happen is the right way. The phrases "enable mDNS" and "advertiser mode" are what confused me, since "enabling" and "mode" sound like one-time operations that repeatedly advertise.

    By the way, that is exactly what I'm doing but mDNS Watch fails to ever list my device. I also have been unable to find any reliable Windows programs or libraries for scanning/discovery that don't give cryptic errors or hang indefinitely (other than Wireshark, but that won't help in an application).

  • Vishal Talwar said:
    ...after experimentation did I find that periodically calling it as long as you want advertising to happen is the right way.

    Although regular mDNS broadcasts will work it is not the right way.  Devices should not do this for a variety of reasons, such as breaking name conflict resolution and flooding the network. 

    From RFC6762:

    "In particular, a Multicast DNS responder MUST NOT send regular periodic announcements as a matter of course."

  • Ah, then I'm thoroughly misunderstanding mDNS it seems. Do you have any suggestions how to use the announcement function properly if not periodically? I would like to have a custom mobile app that discovers my device without any trouble to the user beyond the initial Smart Config process, after which this would be the natural second step.

  • Vishal Talwar said:
    Ah, then I'm thoroughly misunderstanding mDNS it seems. Do you have any suggestions how to use the announcement function properly if not periodically?

    The correct way is join the Bonjour multicast group (it's a specific ip and port) and listen for mDNS requests for your device and only then should you respond to the mDNS Request with the canned message provided via the CC3000 mDNS Advertise command.  To do this, you will have to consume one of the 4 sockets to continuously listen for these requests. 

    This is the main part of my disappointment.  I thought, TI was handling the mDNS stuff and I would have 4 sockets with which to implement my web server and UDP service.   

  • I have to agree with Valkyrie-MT here.

    I really appreciate that the actual TI employees that work on a project contribute to answering questions about the resulting products.

    It's great that Tomer has provided input and told us that "target.local" will be fixed in the next release, and made a clear statement that they have no plans for mDNS query support.

    Having said that I think the message, where he aplogizes "if the press release was not clear" relating to mDNS capabilities, is a bit disingenuous.

    I would say "clear" is not the right word here, "incorrect" would be better. I don't think one canned mDNS message can in any way be conceived to constitute any kind of real support for mDNS.

    E.g. if I created a system that could do nothing more than send one canned GET request I could hardly claim to support HTTP in any real sense.

    The current CC3000 canned mDNS message isn't really good for much else than letting the Smart Config setup application know that the relevant CC3000 device has connected to the network and that it can stop sending out the SSID and password information.

    Service discovery involves clients querying for, i.e. discovering, devices that support the given service the client is interested in. The CC3000, as has been clearly determined above, does not provide querying support.

    As to Vishal Talwar's last question - as Valkyrie-MT says if you want to do things properly then you will have to accept that the CC3000 as it stands doesn't provide all that you need and that you will have to provide some level of query support in your own code.

  • Aha, thanks George and Valkyrie-MT!

    So the choices are - abuse the mDNS protocol by promiscuously advertising yourself (and even then, fail to be recognized by generic programs like mDNS watch), or DIY yee-haw your way to a solution. The discovery feature was #3 on the list of reasons to use the CC3000, the first two being Smart Config and price.

    In any case, I don't want to sound ungrateful for all of the work that went into making the module this easy to use to begin with. The ability to do Smart Config alone makes this worth it even if discovery has to be solved in some custom way.

  • Tomer - I asked some more questions about the CC3000 DNS-SD/mDNS related behavior on the Apple Bonjour developer mailing list.

    This mailing list seems to be the definitive place to go for Bonjour related issues.

    It seems there are a few more issues, in particular by publishing a SRV record the CC3000 is treating the pseudo service _device-info as if it were a real service when it should not.

    This is discussed here:

    http://lists.apple.com/archives/bonjour-dev/2013/Oct/msg00000.html

    Publishing a SRV record means that at the moment on Mac OS X you can use dns-sd to browse for _device-info._udp as if it were a real service like so:

    $ dns-sd -L CC3000 _device-info._udp

    Lookup CC3000._device-info._udp.local
    DATE: ---Mon 16 Sep 2013---
    15:14:22.579 ...STARTING...
    15:14:22.580 CC3000._device-info._udp.local. can be reached at target.local.:1234 (interface 4)
    dev=CC3000 vendor=Texas-Instruments"

    Note: as the CC3000 does not support querying this will only work if the Mac in question was on and was able to cache the relevant mDNS message when published by the CC3000.

    This should not work, and only works because of the SRV record that should not be part of the canned CC3000 mDNS message.

    This is discussed further in this Bonjour developer mailing list message:

    http://lists.apple.com/archives/bonjour-dev/2011/Jul/msg00016.html

    And from both these mailing list messages it does look as if the service should be _device-info._tcp and not _device-info._udp.

    Perhaps someone on the CC3000 project should purchase:

    Zero Configuration Networking : The Definitive Guide by Stuart Cheshire & Daniel H. Steinberg, ISBN# 0-596-10100-7

    [ This book is recommended by Rory L. P. McGuire who is a member of Apple's Mac OS X Networking Group and is actually working on Bonjour. ]

    At the very least the records in the canned CC3000 mDNS message should be fixed up so it's all correct, and at the same time I think some more consideration should be given to everything that Valkyrie-MT has brought up.

    In the meantime I do really think any claim to any kind of reasonable DNS-SD or mDNS support should be removed from CC3000 related documentation or promotional literature.

  • Hi George,

    We're NOT Bonjour complaint. You're correct about it. As said already, I will make sure to clarify/correct this on our wiki, and also to post an updated MRKT announcement about it.  I will also fix the "target.local" to the correct name, as it should  be.

    As for your statement:

    "It seems there are a few more issues, in particular by publishing a SRV record the CC3000 is treating the pseudo service _device-info as if it were a real service when it should not".

    You're correct about it, but since we are not Bonjour complaint, I don't think there's an issue advertising such packet. The reason we added this as a service was to allow service discovery and Bonjour application (running on phones for example) to be able to detect the CC3000 device, and retrieve the information as the device's name, IP address (as can be seen in the example of the CC3000 mdns wiki page).. 

    If we were not publishing this information as a service, the packet was indeed Bonjour complaint, but the device could not have been detected by those applications.

    If you look at the following example, as executed on a Mac machine, you will notice that the packet we advertise is exactly the same. Again, I'm not saying it's aligned with Bonjour spec, but it is possible to generate such a packet even on a Mac machine:

    dns-sd -R Avi _device-info._udp . 1234 ver=1.0.1

     

    where on the CC3000 device (assuming the name is "tomer") it will look like:

    which you can see is exactly the same.

    As for the tcp/udp issue, I'm not sure it's a real issue, same as my previous comment. 

    Regards,

    Tomer

  • Hi George, Valkyrie-MT, Vishal and others,

    I am posting this to see whether any of you has progressed with a solution for the mDNS issues?

    I am having issues with even promiscuously advertising via the mdnsAdvertiser method. When I first start my device I am able to find the the IP address that is being sent by the mdnsAdvertiser packet. However, after a while this does not even seem to work. (which then requires the device to be restarted)

    I have included this code in my main program loop, so it gets trigged in a spam like way constantly.

    mdnsAdvertiser(1,device_name,strlen(device_name));

    And I use this Objective C IOS Code to obtain the IP from the mdnsPacket.

    - (NSString*)ipAddressFromHostName: (NSString*)hostName
    {
        self.statusDescription.text = @"Searching";
    
        struct addrinfo hints;
        memset(&hints, 0, sizeof(hints));
        hints.ai_family = PF_INET;   //PF_UNSPEC for both IPv4 and IPv6 - Use PF_INET if you want only IPv4 addresses
        hints.ai_protocol = IPPROTO_TCP;
    
        struct addrinfo *addrs, *addr;
        getaddrinfo("target.local", NULL, &hints, &addrs);
    
        for (addr = addrs; addr; addr = addr->ai_next)
        {
            char host[NI_MAXHOST];
            getnameinfo(addr->ai_addr, addr->ai_addrlen, host, sizeof(host), NULL, 0, NI_NUMERICHOST);
            printf("%s\n", host);
            self.statusDescription.text = @"Connected";
            return [NSString stringWithFormat:@"%s", host];
        }
    
        return [NSString stringWithFormat:@"Not Found"];
        freeaddrinfo(addrs);
    }

    If anyone has any suggestions on what can be done to get discovery to function, it would be great to hear back from you. 

    Glenn.

  • Hi Glen --

    I think the first thing to accept is that the CC3000 at the moment, despite claims by TI to the contrary, has no real mDNS support.

    At the moment the CC3000 is like a co-worker who on entering the office in the morning says hi to everyone, i.e. announces his presence, but from then on refuses to respond to any greeting from anyone else for the rest of the day.

    I really don't recommend spamming - this absolutely isn't how mDNS is supposed to work.

    Adafruit have produced a library for minimal mDNS support (A records only I think) - note this will cost you one of your precious few sockets but it will do proper query/response handling rather than spamming. Note: I haven't used this library so I can't comment on how well it works.

    I've written up some details about the CC3000 and mDNS here - but from your post I think you probably already know most of what I point out.

  • Hi George,

    Thanks for getting back to me and letting me know about the Adafruit library. That may sort out things for me, as I only require one UDP socket with my application.

    Yes, it is a shame about where the CC3000 is at the moment. It really has so much promise, the simplicity is just amazing and enables people with very low level of skills to add a device to a network. This is essential for so many consumer products.

    I am trying to be patient about this issue and another one that is affecting my ability to develop IOS apps. I understand the difficulties TI must be facing, I used to work for a large vendor in a support and engineering role. I just hope that senior management put the resources behind the CC3000, as this could be a really successful product for TI, as no one else comes close to the simplicity that it provides. 

    Regarding your site....I have read most of the posts on it....it was very informative and great to understand what is actually happening. As when I show people how simple it is to add my device to a wifi network, they are amazed and very curious as to how this can be possible.

    Thanks again, and all the best with the work you do......I am off to Adafruit to see if I can get their mDNS library working on the Tiva C.

  • Hi Glenn,

    Can you please explain in detail what excatly happens? Can you please share the air sniffer logs as well?

    Thanks & Regards,

    Raghavendra

  • Hi Raghavendra,

    I'd really like to have help in resolving the issue. However I do not believe anything can be done till this has been fixed, hopefully in the next update. 

    Or are you saying there may be something you can do to assist?

    As for explaining in detail, not sure I could go into any more depth than what I have included 4 posts above.

    Here is the packet that gets sent by mdnsAdvertiser

      Frame: Number = 7759, Captured Frame Length = 286, MediaType = WiFi
    - WiFi: [Unencrypted Data] F....DP, (I) RSSI = -50 dBm, Rate = 1.0 Mbps
      - MetaData: RSSI = -50 dBm, Rate = 1.0 Mbps
         Version: 2 (0x2)
         Length: 32 (0x20)
       - OpMode: Extensible Station Mode
          StationMode:           (...............................0) Not Station Mode
          APMode:                (..............................0.) Not AP Mode
          ExtensibleStationMode: (.............................1..) Extensible Station Mode
          Unused:                (.0000000000000000000000000000...)
          MonitorMode:           (0...............................) Not Monitor Mode
         Flags: 0 (0x0)
         PhyType: Undefined Value (0)
         Channel: Undefined PhyType 0, Center Frequency: 2412 MHz
         lRSSI: -50 dBm
         Rate: 1.0 Mbps
         TimeStamp: 11/29/2013, 15:28:33.252689 UTC
      - FrameControl: Version 0,Data, Data, F....DP(0x6208)
         Version:        (..............00) 0
         Type:           (............10..) Data
         SubType:        (........0000....) Data
         DS:             (......10........) DS to STA via AP
         MoreFrag:       (.....0..........) No
         Retry:          (....0...........) No
         PowerMgt:       (...0............) Active Mode
         MoreData:       (..1.............) Yes
         ProtectedFrame: (.1..............) Yes
         Order:          (0...............) Unordered
        Duration: 0 (0x0)
        DA: 01005E 0000FB
        BSSID: E091F5 E7890A
        SA: Texas Instruments 57F2D6
      - SequenceControl: Sequence Number = 3455
         FragmentNumber: (............0000) 0
         SequenceNumber: (110101111111....) 3455
    - LLC: Unnumbered(U) Frame, Command Frame, SSAP = SNAP(Sub-Network Access Protocol), DSAP = SNAP(Sub-Network Access Protocol)
      - DSAP: SNAP(Sub-Network Access Protocol), Individual DSAP
         Address: (1010101.) SNAP(Sub-Network Access Protocol)
         IG:      (.......0) Individual Address
      - SSAP: SNAP(Sub-Network Access Protocol), Command
         Address: (1010101.) SNAP(Sub-Network Access Protocol)
         CR:      (.......0) Command Frame
      - Unnumbered: UI - Unnumbered Information
         MMM:  (000.....) 0
         PF:   (...0....) Poll Bit - No Response Solicited
         MM:   (....00..)
         Type: (......11) Unnumbered(U) Frame
    - Snap: EtherType = Internet IP (IPv4), OrgCode = XEROX CORPORATION
        OrganizationCode: XEROX CORPORATION, 0(0x0000)
        EtherType: Internet IP (IPv4), 2048(0x0800)
    - Ipv4: Src = 192.168.1.15, Dest = 224.0.0.251, Next Protocol = UDP, Packet ID = 10, Total IP Length = 222
      - Versions: IPv4, Internet Protocol; Header Length = 20
         Version:      (0100....) IPv4, Internet Protocol
         HeaderLength: (....0101) 20 bytes (0x5)
      - DifferentiatedServicesField: DSCP: 0, ECN: 0
         DSCP: (000000..) Differentiated services codepoint 0
         ECT:  (......0.) ECN-Capable Transport not set
         CE:   (.......0) ECN-CE not set
        TotalLength: 222 (0xDE)
        Identification: 10 (0xA)
      - FragmentFlags: 0 (0x0)
         Reserved: (0...............)
         DF:       (.0..............) Fragment if necessary
         MF:       (..0.............) This is the last fragment
         Offset:   (...0000000000000) 0
        TimeToLive: 1 (0x1)
        NextProtocol: UDP, 17(0x11)
        Checksum: 5715 (0x1653)
        SourceAddress: 192.168.1.15
        DestinationAddress: 224.0.0.251
    - Udp: SrcPort = 1654, DstPort = 5353, Length = 202
        SrcPort: 1654
        DstPort: 5353
        TotalLength: 202 (0xCA)
        Checksum: 27336 (0x6AC8)
      - UDPPayload: SourcePort = 1654, DestinationPort = 5353
         UDPPayloadData: Binary Large Object (194 Bytes)
    
    
    Data
    
    00 00 84 00 00 00 00 05 00 00 00 00 0C 5F 64 65 76 69 63 65 2D 69 6E 66 6F 04 5F 75 64 70 05 6C 6F 63 61 6C 00 00 0C 00 01 00 00 11 94 00 0E 0B 4C 69 67 68 74 53 65 72 76 65 72 C0 0C 09 5F 73 65 72 76 69 63 65 73 07 5F 64 6E 73 2D 73 64 04 5F 75 64 70 05 6C 6F 63 61 6C 00 00 0C 00 01 00 00 11 94 00 02 C0 0C C0 2F 00 10 80 01 00 00 11 94 00 24 0A 64 65 76 3D 43 43 33 30 30 30 18 76 65 6E 64 6F 72 3D 54 65 78 61 73 2D 49 6E 73 74 72 75 6D 65 6E 74 73 C0 2F 00 21 80 01 00 00 11 94 00 0F 00 00 00 00 04 D2 06 74 61 72 67 65 74 C0 1E C0 A9 00 01 80 01 00 00 11 94 00 04 C0 A8 01 0F 
    
    ..„.........._device-info._udp.local........”...LightServerÀ.._services._dns-sd._udp.local........”..À.À/..€....”.$.dev=CC3000.vendor=Texas-InstrumentsÀ/.!€....”.......Ò.targetÀ.À©..€....”..À¨..

    Glenn. 

  • I hope others do not mind if I hijack this post to see if we can work together to create a custom mdns solution. I really need to get discovery working, as this makes the difference between a product only suitable for geeks and one that the average consumer can use. If you also are in the same boat, then please contribute if you can.

    Ok, so I have headed over to Adafruit and obtained their mdsn code, which can be found here - https://github.com/adafruit/CC3000_MDNS , they have also written an entire implementation for the CC3000, which can be found here - https://github.com/adafruit/Adafruit_CC3000_Library

    I then ported the C++ code into C code (as integrating the C++ into my code was creating its own challenges).

    So this is what I end up with...

    mdns.c

    /*
    CC3000 Multicast DNS 
    Version 1.0
    Copyright (c) 2013 Tony DiCola (tony@tonydicola.com)
    
    License (MIT license):
      Permission is hereby granted, free of charge, to any person obtaining a copy
      of this software and associated documentation files (the "Software"), to deal
      in the Software without restriction, including without limitation the rights
      to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      copies of the Software, and to permit persons to whom the Software is
      furnished to do so, subject to the following conditions:
    
      The above copyright notice and this permission notice shall be included in
      all copies or substantial portions of the Software.
    
      THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
      THE SOFTWARE.
    
    */
    
    // Important RFC's for reference:
    // - DNS request and response: http://www.ietf.org/rfc/rfc1035.txt
    // - Multicast DNS: http://www.ietf.org/rfc/rfc6762.txt
    
    #include <stdio.h>
    #include <stdint.h>
    #include <stdbool.h>
    #include <string.h>
    #include <ctype.h>
    #include <stdlib.h>
    
    /* SimpleLink Wi-Fi Host Driver Header files */
    #include <ti/drivers/wifi/cc3000/hci.h>
    #include <ti/drivers/wifi/cc3000/netapp.h>
    #include <ti/drivers/wifi/cc3000/nvmem.h>
    #include <ti/drivers/wifi/cc3000/socket.h>
    #include <ti/drivers/wifi/cc3000/wlan.h>
    
    #include <xdc/std.h>
    
    #include "mdns.h"
    
    #define HEADER_SIZE 12
    #define QDCOUNT_OFFSET 4
    #define A_RECORD_SIZE 14
    #define NSEC_RECORD_SIZE 20
    #define TTL_OFFSET 4
    #define IP_OFFSET 10
    
      static uint8_t queryHeader[];
      uint8_t* queryFQDN;
      int queryFQDNLen = 0;
      // Current parsing state
      uint8_t* current;
      int currentLen = 0;
      int index = 0;
      uint8_t FQDNcount = 0;
      // Response data
      uint8_t* response;
      int responseLen = 0;
      // Socket for MDNS communication
      static int mdnsSocket;
    
    // TODO: Put these in flash, or refactor away into better state handling.
    uint8_t queryHeader[] = {
      0x00, 0x00, // ID = 0
      0x00, 0x00, // Flags = query
      0x00, 0x00, // Question count = ignored
      0x00, 0x00, // Answer count = ignored
      0x00, 0x00, // Name server records = ignored
      0x00, 0x00  // Additional records = ignored
    };
    
    int mdnsSocket = -1;
    
    ////////////////////////////////////
    // mdnsResponder
    ////////////////////////////////////
    bool mdnsBegin(const char* domain, uint32_t ttlSeconds)
    { 
      // Construct DNS request/response fully qualified domain name of form:
      // <domain length>, <domain characters>, 5, "local"
      size_t n = strlen(domain);
      if (n > 255) {
        // Can only handle domains that are 255 chars in length.
        return false;
      }
      int queryFQDNLen = 8 + n;
      if (queryFQDN != NULL) {
        free(queryFQDN);
      }
      queryFQDN = (uint8_t*) malloc(queryFQDNLen);
      if (queryFQDN == NULL) {
        return false;
      }
      queryFQDN[0] = (uint8_t)n;
      // Copy in domain characters as lowercase
      int i;
      for (i = 0; i < n; ++i) {
        queryFQDN[1+i] = tolower(domain[i]);
      }
      // Values for 5 (length), "local":
      uint8_t local[] = { 0x05, 0x6C, 0x6F, 0x63, 0x61, 0x6C };
      memcpy(&queryFQDN[1+n], local, 6);
      queryFQDN[7+n] = 0;
    
      // Construct DNS query response
      // TODO: Move these to flash or just construct in code.
      uint8_t respHeader[] = { 0x00, 0x00,   // ID = 0
                               0x84, 0x00,   // Flags = response + authoritative answer
                               0x00, 0x00,   // Question count = 0
                               0x00, 0x01,   // Answer count = 1
                               0x00, 0x00,   // Name server records = 0
                               0x00, 0x01    // Additional records = 1
      };
    
      // Generate positive response for IPV4 address
      uint8_t aRecord[] = { 0x00, 0x01,                // Type = 1, A record/IPV4 address
                            0x80, 0x01,                // Class = Internet, with cache flush bit
                            0x00, 0x00, 0x00, 0x00,    // TTL in seconds, to be filled in later
                            0x00, 0x04,                // Length of record
                            0x00, 0x00, 0x00, 0x00     // IP address, to be filled in later
      };
    
      // Generate negative response for IPV6 address (CC3000 doesn't support IPV6)
      uint8_t nsecRecord[] = {  0xC0, 0x0C,                // Name offset
                                0x00, 0x2F,                // Type = 47, NSEC (overloaded by MDNS)
                                0x80, 0x01,                // Class = Internet, with cache flush bit
                                0x00, 0x00, 0x00, 0x00,    // TTL in seconds, to be filled in later
                                0x00, 0x08,                // Length of record
                                0xC0, 0x0C,                // Next domain = offset to FQDN
                                0x00,                      // Block number = 0
                                0x04,                      // Length of bitmap = 4 bytes
                                0x40, 0x00, 0x00, 0x00     // Bitmap value = Only first bit (A record/IPV4) is set
      }; 
    
    
      // Allocate memory for response.
      int responseLen = HEADER_SIZE + queryFQDNLen + A_RECORD_SIZE + NSEC_RECORD_SIZE;
      if (response != NULL) {
        free(response);
      }
      response = (uint8_t*) malloc(responseLen);
      if (response == NULL) {
        return false;
      }
      // Copy data into response.
      memcpy(response, respHeader, HEADER_SIZE);
      memcpy(response + HEADER_SIZE, queryFQDN, queryFQDNLen);
      uint8_t* records = response + HEADER_SIZE + queryFQDNLen;
      memcpy(records, aRecord, A_RECORD_SIZE);
      memcpy(records + A_RECORD_SIZE, nsecRecord, NSEC_RECORD_SIZE);
      // Add TTL to records.
      uint8_t ttl[4] = { (uint8_t)(ttlSeconds >> 24), (uint8_t)(ttlSeconds >> 16), (uint8_t)(ttlSeconds >> 8), (uint8_t)ttlSeconds };
      memcpy(records + TTL_OFFSET, ttl, 4);
      memcpy(records + A_RECORD_SIZE + 2 + TTL_OFFSET, ttl, 4);
    
      // Add IP address to response
      uint32_t ipAddress;
    
      uint32_t netmask;
      uint32_t gateway;
      uint32_t dhcpserv;
      uint32_t dnsserv;
    
      if(!getIPAddress(&ipAddress, &netmask, &gateway, &dhcpserv, &dnsserv))
      {
        return false;
      }
    
    
      records[IP_OFFSET]     = (uint8_t)(ipAddress >> 24);
      records[IP_OFFSET + 1] = (uint8_t)(ipAddress >> 16);
      records[IP_OFFSET + 2] = (uint8_t)(ipAddress >> 8);
      records[IP_OFFSET + 3] = (uint8_t) ipAddress;
      
    
      // Open the MDNS socket if it isn't already open.
      if (mdnsSocket == -1) {
        // Create the UDP socket
        int soc = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
        if (soc < 0) {
          return false;
        }
        // Use port 5353 and listen/send to the multicast IP 224.0.0.251
        sockaddr_in address;
        memset(&address, 0, sizeof(address));
        address.sin_family = AF_INET;
        address.sin_port = htons(5353);
        address.sin_addr.s_addr = htonl(IP2U32(224, 0, 0, 251));
        socklen_t len = sizeof(address);
        if (bind(soc, (sockaddr*) &address, sizeof(address)) < 0)
        {
          return false;
        }
        mdnsSocket = soc;
      }
    
      // Start in a state of parsing the DNS query header.
      mdnsChangeState(queryHeader);
    
      return true;
    }
    
    ////////////////////////////////////
    // mdnsUpdate
    ////////////////////////////////////
    void mdnsUpdate()
    {
      // Check if data is available to read using select
      timeval timeout;
      timeout.tv_sec = 0;
      timeout.tv_usec = 5000;
      fd_set reads;
      FD_ZERO(&reads);
      FD_SET(mdnsSocket, &reads);
      select(mdnsSocket + 1, &reads, NULL, NULL, &timeout);
      if (!FD_ISSET(mdnsSocket, &reads)) {
        // No data to read.
        return;
      }
      // Read available data.
      uint8_t buffer[20];
      int n = recv(mdnsSocket, &buffer, sizeof(buffer), 0);
      if (n < 1) {
        // Error getting data.
        return;
      }
    
      int i;
      // Compare incoming data to expected data from current state.
      for (i = 0; i < n; ++i)
      {
        uint8_t ch = buffer[i];
        // If we're processing an FQDN character, make the comparison case insensitive.
        if (current == queryFQDN && FQDNcount > 0)
        {
          ch = tolower(ch);
        }
        // Check character matches expected, or in the case of parsing the question counts
        // ignore it completely (this is done because MDNS queries on different platforms
        // sometimes ask for different record types).
        if (ch == current[index] || (current == queryHeader && index >= QDCOUNT_OFFSET))
        {
          // Update FQDN char count when processing FQDN characters.
          if (current == queryFQDN)
          {
            if (FQDNcount == 0)
            {
              // Handle the next characters as case insensitive FQDN characters.
              FQDNcount = ch;
            }
            else
            {
              FQDNcount--;
            }
          }
          // Update state when the end of the current one has been reached.
          index = index + 1;
          if (index >= currentLen)
          {
            // Switch to next state
            if (current == queryHeader) {
              mdnsChangeState(queryFQDN);
            }
            else if (current == queryFQDN)
            {
              mdnsSendResponse();
              mdnsChangeState(queryHeader);
            }
          }
        }
        else
        {
          // Reset to start looking from the start again
          mdnsChangeState(queryHeader);
        }
      }
    	return;
    }
    
    ////////////////////////////////////
    // mdnsChangeState
    ////////////////////////////////////
    void mdnsChangeState(uint8_t* state) {
    
      current = state;
      if (state == queryFQDN)
      {
        currentLen = queryFQDNLen;
      }
      else if (state == queryHeader)
      {
        currentLen = HEADER_SIZE;
      }
      index = 0;
      int FQDNcount = 0;
    }
    
    ////////////////////////////////////
    // mdnsSendResponse
    ////////////////////////////////////
    void mdnsSendResponse()
    {
      send(mdnsSocket, response, responseLen, 0);
    }
    
    
    /**************************************************************************/
    /*!
        @brief  Helper function to convert four bytes to a U32 IP value
    */
    /**************************************************************************/
    //uint32_t Adafruit_CC3000::IP2U32(uint8_t a, uint8_t b, uint8_t c, uint8_t d)
    uint32_t IP2U32(uint8_t a, uint8_t b, uint8_t c, uint8_t d)
    {
      uint32_t ip = a;
      ip <<= 8;
      ip |= b;
      ip <<= 8;
      ip |= c;
      ip <<= 8;
      ip |= d;
    
      return ip;
    }
    
    /**************************************************************************/
    /*!
        @brief   Reads the current IP address
    
        @returns  False if an error occured!
    */
    /**************************************************************************/
    bool getIPAddress(uint32_t *retip, uint32_t *netmask, uint32_t *gateway, uint32_t *dhcpserv, uint32_t *dnsserv)
    {
      //if (!_initialised) return false;
      //if (!ulCC3000Connected) return false;
      //if (!ulCC3000DHCP) return false;
    
      tNetappIpconfigRetArgs ipconfig;
      netapp_ipconfig(&ipconfig);
    
      /* If byte 1 is 0 we don't have a valid address */
      if (ipconfig.aucIP[3] == 0) return false;
    
      memcpy(retip, ipconfig.aucIP, 4);
      memcpy(netmask, ipconfig.aucIP+4, 4);
      memcpy(gateway, ipconfig.aucIP+8, 4);
      memcpy(dhcpserv, ipconfig.aucIP+12, 4);
      memcpy(dnsserv, ipconfig.aucIP+16, 4);
    
      return true;
    }

    mdns.h

    #ifndef CC3000_MDNS_H
    #define CC3000_MDNS_H
    
      bool mdnsBegin(const char* domain, uint32_t ttlSeconds);
      void mdnsUpdate();
      uint32_t IP2U32(uint8_t a, uint8_t b, uint8_t c, uint8_t d);
      bool getIPAddress(uint32_t *retip, uint32_t *netmask, uint32_t *gateway, uint32_t *dhcpserv, uint32_t *dnsserv);
      void mdnsChangeState(uint8_t* state);
      void mdnsSendResponse();
    
    #endif
    

    Program Code

    :
    :
    
        if (!mdnsBegin("test.local", 3600))
        {
        	System_printf("msdnBegin Failed");  // I am using TI-RTOS, you can change this to printf or what ever you use
        }
    
        while(1)
        {
    
             mdnsUpdate();
    
             :
         }

    Problems:

    1. My code uses UDP and I am having issues when I bind to UDP for my app and when the above code also binds. Not sure how I go about opening a new socket without it conflicting with a previous one. No issue if I turn one of the sockets to TCP
    2. The above code does not seem to be sending any packets out that I can capture with network sniffer.
    3. My app does not seem to want to start when I include the mdnsUpdate()

    Feel free to join in trying to get this to work. It will help a lot of us out there, who need some mechanism for discovery.

  • Hi Glenn --

    Thanks for your positive comments about my CC3000 related blog postings :)

    First thing - I don't know what environment you're working in but I think it probably is worth the trouble to work out how to integrate C++ code into your project even if your code is going to be all classic C.

    This isn't because I think C++ is the best thing ever - it's because I think you'll get more traction/help if you work with the various existing CC3000 libraries, that are mainly C++ based, than trying to move people your direction and getting them to look into a C variant of an existing library.

    Most modern environments that support C generally also support C++ with no extra effort and you can generally keep the C++ to a minimum if you want to carry on in C while using a few C++ libraries.

    Second thing - I think the TI forums are good for definitive comments on behavior and bugs but I think there are probably better places if you want to work on implementing open source libraries for TI products.

    E.g. the following:

    • http://forums.adafruit.com/viewforum.php?f=22 - Adafruit - all their CC3000 discussion seems to go on in the "Other Arduino products from Adafruit" subforum - I guess as they produce an Arduino shield for the CC3000 but they also produce a very nice non-Arduino specific breakout board.
    • https://community.sparkdevices.com/ - Spark Core is a product built around the CC3000 - they're nice people there and probably know more about the CC3000 than anyone else at this stage (though they're just shipping their first product at the moment so I think things are kind of hectic there at the moment!).
    • http://www.soldersplash.co.uk/products/wifi-dipcortex/ - the guys at DipCortex currently seem to be driving the mbed, i.e. ARM Cortex M3, related library development - see also http://mbed.org/cookbook/cc3000 (from the DipCortex guys too).

    Again all of these revolve around C++ libraries.

    Best of luck getting something that works for you.

    PS sorry in advance if I don't follow up on subsequent postings - I'm really really supposed to be focusing on other things at the moment :)

  • I see some folks are just implementing their own local name resolution using a UDP socket.  I have implemented my own local name resolution and it seems to work (mDNS and NetBIOS Naming).  By allowing for Multicast UDP support, the cc3000 allows you to do whatever you want (albeit at the expense of one of the 4 sockets).  Having said that, I think TI should move to implementing mDNS in the host driver code and remove it completely from the firmware as it is too rigid as implemented in the firmware.  Once they do this, they can free up some space in the firmware and actually fulfill their original statements about mDNS support and discovery.  I have discovery via mDNS implemented right now and it works. 

    FYI, all my C# source code can be found at http://cc3000.codeplex.com

    I have found that you can implement a web server that uses 2 sockets and mDNS and NetBIOS naming with the other 2.  This gives me a functional platform.  I would have appreciated 1 or 2 more sockets, but I will make this work. 

    -Valkyrie-MT

  • Hi Glenn,

    Thank you for the  details. The 'target.local' issue would be fixed in next release of v1.12 soon.

    Thanks & Regards,

    Raghavendra

  • @George:  

    I am working with the Tiva C LaunchPad (ARM Cortex M4F), TI-RTOS and Code Composer Studio 5.5 for my development environment. So a pure TI implementation throughout. (I spend a lot of money of TI software and parts).

    Regarding C++, I got stuck here - http://e2e.ti.com/support/development_tools/compiler/f/343/t/306292.aspx

    Thanks for the links to the other projects. My callout was for TI controllers and compilers, so that would include ARM and MSP430, I should have been more specific.

    And understood about your need to focus energy elsewhere. Thanks for taking the time to respond.

    @Valkyrie-MT:

    As my background is in .Net, I had a good look at the .Net MicroFramework when I started my project but rejected it due to the lack of support for the CC3000. How funny, that you have likely got a more complete implementation than what is provided by TI. In fact, lots of 3rd parties are creating libraries and code that fix the TI bugs. So, you can now get a working mDNS for the CC3000 for .Net MicroFramework and Arduino.  But not for the new flagship IOT/Cloud MCU from TI, the Tiva C.

    You say by allowing Multicast UDP support to CC3000 it allows you to do whatever you want. I believe this may be the cause of my problem 1) above. How do I go about allowing Multicast support?

  • @Raghavendra:

    Thanks for getting back to me, very much appreciated.

    I am aware that the target.local issue will be resolved in the next release. As in you will now be able to set the name to say cc3000.local or raghavendra.local and will not be restricted to use target.local

    Questions:

    1) Does this also mean that mdns will also be fixed so that discovery will function as it should. In other words, will the mdnsAdvertiser method behave as it should? Will I be able to obtain the IP address of my device by querying the name from an external device (in my case an iPhone)?

    2) When you say soon, how soon will this be? I have people waiting for a functioning device, they are expecting it in the next few weeks, and this is the biggest show stopper I have. Should I wait for the TI fix and work on other issues....or should I continue to develop my own mdns solution?

    3) If a fix has already been developed can you provide a QFE (quick fix engineering) or whatever hotfixes are called at TI? I'd happily be a tester for the fix, and understand it has yet to go through regression testing etc. You can contact me directly at glenn at vassallo dot com

    I look forward to your answers to my questions!

    Glenn.

  • Hi Glenn,

    1)  The mdnsAdvertiser currently works with the TI recommended applications as mentioned in the wiki. And as mentioned earlier, we're not mDNS Bonjour compliant. If this issue is reproduced in any other way, other than our recommended way of testing, we will not be fixing it.

    2) We are in the process of making a release, and it would take few weeks.


    3) If we have a fix, we will make the engineering drop available. But it will be an un-official one.

    Thanks & Regards,

    Raghavendra

  • Hi Raghavendra,

    Thank you so much for your prompt and clear response!!!

    1) Fantastic, as I only require mdns to function as specified on this Wiki page - http://processors.wiki.ti.com/index.php/CC3000_mDNS  . Currently the msdnAdvertiser() method does not function as described on this wiki page, as it only semi-works initially, but not once the first packet times-out.  

    Are you saying that this has now been resolved and that mdnsAdvertiser will function as per this Wiki page?

    2) Again, Fantastic, I cannot wait for it to be released, as I am sure are many others. 

    3) Please do provide me the engineering drop if available. I totally understand this is un-official and not fully tested. I used to work as an Escalation Engineer for an unnamed software vendor, so clearly understand what I will be receiving. I will keep it private and confidential. You can send it to glenn at vassallo dot com

    Once again, thanks for your response....very much appreciated.

    Glenn.

  • Glenn Vassallo said:
    You say by allowing Multicast UDP support to CC3000 it allows you to do whatever you want. I believe this may be the cause of my problem 1) above. How do I go about allowing Multicast support?

    For mDNS I do the following:

    1. Open a new UDP Socket. 
    2. On the new socket, Bind to Multicast address 224.0.0.251:5353 (reserved for mDNS)
    3. On the new socket, call HCI_CMND_RECVFROM every 500ms. 

    Honestly, there is nothing to differentiate this from a regular UDP connection.  The difference is the use of the Multicast address.  So, all the multicast group magic really just happens on the router. 

     -Valkyrie-MT

  • Hi Glenn,

    The way we test it, for example with Bonjour Browser on Android.

    We connect the Android device and the CC3000 to the same AP. On the Android device/browser, start scanning the 'local' domain as soon as mdnsAdvertiser starts on CC3000. I could scan and get the device under 'device info' as '_device-info._udp'. And follow the application options, It would display Text, SRV port, SRV Target, IP address from the Answers.

    Please note, mDns advertisement packets are send every 30 seconds.

    Thanks & Regards,

    Raghavendra

  • Hi Raghavendra,

    That is the exact same way that I test mdnsAdvertiser. The only difference is I am on IOS and use the Discovery and mDNS Watch apps, as specified in the wiki. 

    However, this does not work. Discovery and mDNS Watch sometimes will show the _device-info._udp packet, but sometimes not. Also, even when it is shown, it will not show it after it times out, so in an hours time, you can no longer see the device.

    I assure you this is the behaviour I am experiencing, and I believe other are experiencing the exact same bug.

    If this is not what you or the development team experience, then what could be different in my code?

    Glenn.

  • Hi Glenn,

    I'm sorry if I have confused you. I did not mention that you would have to configure in your application, when you would want to send the advertisement packet. The 30 second mentioned above was with respect to sensor application.

    The way we do it is, for example, in the TCP server scenario, we are waiting on a non-blocking 'accept'. i.e, waiting dor the client to connect. And until the client connects to us, we keep advertising the mDns packets based on a timer. In this way you would not miss the advertisement packets.

    You can refer to 'server.c' in HomeAuomation example in the CC3000 SDK (CC3000 SDK\MSP430FR5739\Home Automation Application\Home Automation Source\source\Automation App)

    Thanks & Regards,

    Raghavendra

  • Hi Raghavendra,

    I am afraid I am even more confused from your above post.

    Basically I need to do the following:-

    I need to be able to determine the IP address of my device by querying on its name. This is all I want to do, basic discovery, that lets my app find where the device is located. This ability needs to occur, even when the device has been on for weeks or months at a time.

    1. Can I do this with the current mdnsAdvertiser?
    2. And if so, how do I go about doing this?

    I wait for your response with breathing that is subdued because of emotion...aka bated breath.

    Glenn.

  • Hi Glenn,

    1. Yes, you can do this with current mdnsAdvertiser.

    2. A call to mdnsAdvertiser would advertise it only once. If you would want to advertise it for ever, you would have to keep calling this at regular intervals. Eg: If you want to advertise say once in 5 seconds, call this based on a timer which fires every 5 seconds.

    Thanks & Regards,

    Raghavendra

  • Hi Raghavendra,

    This is not what I am experiencing.

    As explained in this post - http://e2e.ti.com/support/low_power_rf/f/851/p/290584/1065668.aspx#1065668 .  I have placed mdnsAdvertiser in my main program loop, so it is called constantly, yet after a while it no longer advertises the device.

    So if I am not having my device being advertised when I am constantly calling mdnsAdvertiser. One of the following problem has to be the cause:-

    1. A bug in my code
    2. A bug in mdnsAdvertiser

    Now I am not ruling out I have done something wrong, but considering what  am experiencing is also being experienced by others, I am tending to think it is cause 2 above.

    Please let us know your thoughts and should you require, I can put together repro steps.....just let me know.

    Glenn.

    p.s. Anyone else out there who is also experiencing what I have described, please feel free to add your voice to this discussion.

  • Hi Glenn,

    In that case, what's the average time in which you were able to run to reproduce this issue? Reproduction steps would be useful here. Can you please tell me how you do this?

    Thanks & Regards,

    Raghavendra

  • Hi Raghavendra,

    I actually tested this today. It was around 2 hours that I could no longer return the IP address from querying the name.

    I am using almost identical code as provided in the UDP Echo for CC3000 example provided with TI-RTOS. These are the steps to create this project.

    1) Make sure you have installed TI-RTOS and the latest version of CCS
    2) Select TI Resource Explorer from the View menu within CCS
    3) Select TI-RTOS  from the Packages drop down 
    4) Expand ARM - Expand Tiva C Series - Expand Tiva TM4C123GH6PM - Expand Example Projects
    5)  Select UDP Echo for CC3000
    6)  Follow the 4 steps present to install and build the example
    7)  Now you need to add mdnsAdvertiser call somewhere. For me I also have USB involved, so I have a Program Loop that calls USBHCDMain(); So in your case you just need to place a while (true) around the while (flag) section and include mdnsAdvertiser, here is the bit you will need to update in udpEchoCC3000.c

    char device_name[] = "CC3000";
    
    while (true)    
    {
       mdnsAdvertiser(1,device_name,strlen(device_name));
    
       /* Loop while we receive data */
        while (flag) {
            FD_ZERO(&readSet);
            FD_SET(lSocket, &readSet);
    
            /*
             *  Calling select() before recvfrom() is currently recommended when
             *  using the CC3000. It is also a workaround for a potential race in
             *  the CC3000 internals.
             */
            selectRes = select(lSocket + 1, &readSet, NULL, NULL, &timeout);
    
            if ((selectRes > 0) && (selectRes != -1)) {
                if(FD_ISSET(lSocket, &readSet)) {
                    nbytes = recvfrom(lSocket, buffer, UDPPACKETSIZE, 0,
                                     (sockaddr*)&client_addr, &addrlen);
                    if (nbytes > 0) {
                        /* Echo the data back */
                        sendto(lSocket, buffer, nbytes, 0, (sockaddr*)&client_addr,
                               sizeof(client_addr));
                    }
                    else {
                        flag = FALSE;
                    }
                }
            }
    
            if (selectRes == -1) {
                flag = FALSE;
            }
        }
    }

    You can see my previous  posts for the IOS objective C code, but you should also be able to see there is no packet being sent using a sniffer or using the any one of the mDNS tools available for IOS and Android.

    In fact I just used a packet sniffer and can see the packet stops getting sent out within a minute. And this was using the code as I have suggested above.

    Also on subsequent tests, only one packet was being sent and this packet was not consistent. These are 3 different boot ups of the code. Notice how one was reported as PPP instead of UDP. I am using Microsoft Network Monitor 3.4 for packet sniffing, and have used it for 10+ years and never seen it report incorrectly, so I suspect the actual packet is malformed rather than the sniffer making an error.

    332	3:51:01 AM 6/12/2013	23.9062837		192.168.1.11	224.0.0.251	UDP	UDP:SrcPort = 1892, DstPort = 5353, Length = 202	{UDP:26, IPv4:52}
    3130	3:52:26 AM 6/12/2013	109.0276027		192.168.1.11	224.0.0.251	UDP	UDP:SrcPort = 2045, DstPort = 5353, Length = 202	{UDP:104, IPv4:52}
    4367	3:54:00 AM 6/12/2013	203.4747338		192.168.1.11	224.0.0.251	PPP	PPP:ROHC large-CID	{UDP:202, IPv4:52}
    

    I hope my detailed repro steps and explanation are enough for you to reproduce this bug. If you have any questions, please do not hesitate to let me know.

    Thanks again for taking this up and working through it with me!

  • Hi Glenn,

    Thanks for the detailed explanation. I will get a setup on my side and try to reproduce this. Again, I will run this on the setup as recommended on the wiki. I will update you on this, and also get back to you if I need more information.

    Thanks & Regards,

    Raghavendra

  • Hi Raghavendra,

    Just checking in to see how this is getting along. Is there anything else you need from me?

    Glenn.

  • Hi Glenn,

    We have started the process of testing. I will update you with the results once I have the data.

    Thanks & Regards,

    Raghavendra

  • Hi Raghavendra,

    Just checking in to see how the testing is getting along and to make sure you don't need anything further from me?

    I know you are very busy helping many TI customers, so if it helps, I can provide you a CCS project. Or if there is anything else that would assist you, please just let me know. 

    Glenn.

  • Hi Glenn,

    We have run the tests with mDNS server for above 2 hours and 30 mins in our test case, and we did not come across such an issue, where mDNS stops by itself! We keep advertising the packets and the remote phone which either runs 'Discovery' app Or 'Bonjour Browser', shows the received data.

    As I understand, the mDNS server stops abruptly for you, right? Or does the CC3000 disconnects from the AP? Again, as mentioned earlier, we are not completely mDNS Bonjour compliant.

    Thanks & Regards,

    Raghavendra

  • Raghavendra,

    As I understand, the mDNS server stops abruptly for you, right?

    Yes....the mdnsAdvertiser stops sending packets advertising the CC3000.

    Or does the CC3000 disconnects from the AP? 

    No I do not have problem with disconnects.

    The following are possible reasons you are getting such results, you need to adjust your test to compensate for these possible reasons.

    Testing from within your corporate network may be an issue, as you have servers that may cache and broadcast such information for long periods of time. This is why you must test using packet sniffer, preferably on test network. The CC3000 will be used mostly in home networks, not corporate networks. 

    Also, you need to test with different phone than you use when you test when first starting, as the same phone may cache packet for long periods (this is likely a settings). If the mDNS has not stopped, then a new phone should also get the packet. But be careful about the above issue about corporate network.

    So I encourage you to use packet sniffer to see that the packet is no longer sent when calling mdnsAdvertiser. This is the true test.

    Yes, I understand you are not Bonjour compliant, but you agreed previously, that a packet should be sent when calling mdnsAdvertiser. This is not the case, and this is what needs to be tested.

    I know you are busy, but to wait 2 weeks to finally get this response, after I have spent so much time providing you everything required,  is quite upsetting. I really need this bug fixed, it is stopping me from progressing, it will affect many of your customers, I am hoping that you will spend more time on this as soon as you can.

    Your results and efforts have significant impacts on months and months of work, so I hope you understand why this can be quite upsetting.

    Glenn.

  • Hi Glenn,

    I will keep trying this. To speed up the debugging process, can you please give me the logs from CC3000 debug pins, as mentioned in http://processors.wiki.ti.com/index.php/CC3000_Logger. Also can you please provide me the sniffer logs captured along with the debug logs?

    Thanks & Regards,

    Raghavendra

  • Hi Raghavendra,

    Thank you for suggesting some more work I can do to assist you with your job. Unfortunately I do not have the equipment to perform such debug logging, I can send you sniffer logs alone, but these will be similar to the one I and others have provided in previous posts. Also, it should be noted I am a developer using TI development boards and not a custom board at this stage, my solution is based on the Tiva C LaunchPad and the CC3000 Booster Pack. 

    Additionally, the debug logging you have requested will be useful for your developers to debug the CC3000 firmware once solid repro steps for the bug have been identified. Hence we still need to work on getting you to reproduce the bug in your environment. Giving me more work to do, will not assist you in reproducing the bug.

    To assist me in speeding up the process of receiving support. Do TI offer a paid support option? Many vendors offer paid support, where by an experienced support analyst takes ownership of the case. Should it be determined that the case submitted is a bug, then payment is refunded. Is this available from TI?

    Glenn.