virtual_capability reading is giving NULL from C API call

Questions about our enterprise "in the network" WURFL components

virtual_capability reading is giving NULL from C API call

Postby gpatel » Wed Apr 05, 2017 6:23 am

Hi,

I was trying to read all the virtual_capability with the wurfl.xml file (<ver>data.scientiamobile.com - 2016-03-27 00:30:33</ver>).
But wurfl_device_get_virtual_capability(hd, capability); is returning NULL always even wurfl.xml file having virtual_capability the node.

Library version installed is libwurfl-1.4.4.1-1.x86_64

Example:
<device id="generic_smarttv_chromecast" user_agent="Mozilla/5.0 (CrKey armv7l 1.4.15250) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.0 Safari/537.36" fall_back="generic_smarttv_browser">
<group id="product_info">
<capability name="model_name" value="Chromecast"/>
<capability name="brand_name" value="Google"/>
<capability name="release_date" value="2013_july"/>
</group>
<group id="virtual">
<capability name="controlcap_advertised_device_os" value="Chromecast"/>
</group>
</device>

Code Below:
Code: Select all
#define WURFL_FILE "wurfl.xml"
#define WURFL_DATA_FILE "device_capabilities.csv"

/* Extract WURFL device data file in CSV format*/
int function_wurfl_extract_data() {
    wurfl_handle hwurfl = wurfl_create();

    if(wurfl_set_root(hwurfl, WURFL_FILE) != WURFL_OK) {
        fprintf(stderr, "%s\n", wurfl_get_error_message(hwurfl));
        return 0;
    }

    if (wurfl_load(hwurfl) != WURFL_OK) {
        fprintf(stderr, "%s\n", wurfl_get_error_message(hwurfl));
        return 0;
    }
   
    if(!hwurfl) {
        fprintf(stderr, "initialize wurfl handler from wurfl.xml failed\n");
        return -1;
    }
   
    std::ifstream infile(WURFL_FILE);
    std::ofstream ofile(WURFL_DATA_FILE, std::ofstream::out | std::ofstream::trunc);
   
    std::string line;
    char datetime[20];
    ut_get_time_now(datetime, 20);
    while(getline(infile, line)) {
        int pos1 = line.find("device id=\"");
        if(pos1 >= 0) {
           int pos2 = line.find("\"", pos1+11);
           if(pos2 > pos1+11) {
               std::string device_id = line.substr(pos1+11, pos2-pos1-11);
               wurfl_device_handle hdevice = wurfl_get_device(hwurfl, device_id.c_str());
               if(hdevice) {

                   std::string brand_name = wurfl_device_get_capability(hdevice, "brand_name");
                   std::string model_name = wurfl_device_get_capability(hdevice, "model_name");
                   std::string marketing_name = wurfl_device_get_capability(hdevice, "marketing_name");

                   std::string date = wurfl_device_get_capability(hdevice, "release_date")));
                   int pos3 = line.find("user_agent=\"");
                   if(pos3 >= 0) {
                       int pos4 = line.find("\"", pos3+12);
                       if(pos4 > pos3+12) {
                           std::string user_agent = line.substr(pos3+12, pos4-pos3-12);
                           std::cout << "user_agent : " << user_agent << std::endl;
                           wurfl_device_handle hvcdevice = wurfl_lookup_useragent(hwurfl, user_agent.c_str());
                           if(hvcdevice) {
                     
                               std::string advertised_device_os = wurfl_device_get_virtual_capability(hvcdevice, "controlcap_advertised_device_os");
                               std::string advertised_device_os_version = wurfl_device_get_virtual_capability(hvcdevice, "controlcap_advertised_device_os_version");
                               std::string form_factor = wurfl_device_get_virtual_capability(hvcdevice, "controlcap_form_factor");
                               std::string advertised_browser = wurfl_device_get_virtual_capability(hvcdevice, "controlcap_advertised_browser");
                               std::string advertised_browser_version = wurfl_device_get_virtual_capability(hvcdevice, "controlcap_advertised_browser_version");
                               std::string is_smartphone = (strcmp(wurfl_device_get_virtual_capability(hvcdevice, "controlcap_is_smartphone"), "force_false")==0 ? "0" : "1");
                               std::string is_full_desktop = (strcmp(wurfl_device_get_virtual_capability(hvcdevice, "controlcap_is_full_desktop"), "force_false")==0 ? "0" : "1");
                               std::string is_robot = (strcmp(wurfl_device_get_virtual_capability(hvcdevice, "controlcap_is_robot"), "force_false")==0 ? "0" : "1");
                               std::string is_mobile = (strcmp(wurfl_device_get_virtual_capability(hvcdevice, "controlcap_is_mobile"), "force_false")==0 ? "0" : "1");
                               std::string is_phone = (strcmp(wurfl_device_get_virtual_capability(hvcdevice, "controlcap_is_phone"), "force_false")==0 ? "0" : "1");
                               std::string is_app = (strcmp(wurfl_device_get_virtual_capability(hvcdevice, "controlcap_is_phone"), "force_false")==0 ? "0" : "1");
                               std::string is_app_webview = (strcmp(wurfl_device_get_virtual_capability(hvcdevice, "controlcap_is_app_webview"), "force_false")==0 ? "0" : "1");
                        
                               wurfl_device_destroy(hvcdevice);
                               ofile << data << std::endl; //Here data string is comma separeted all fields
                            }
         }
          }
          wurfl_device_destroy(hdevice);
                }
           }
        }
    }
    infile.close();
    ofile.close();
    return 0;
}


Note: ALL of the virtual_capability is returning NULL always.

Thank you, looking forward the support and assistance.
gpatel
 
Posts: 3
Joined: Wed Apr 05, 2017 5:38 am

Re: virtual_capability reading is giving NULL from C API cal

Postby aaronp » Wed Apr 05, 2017 8:59 am

Hello,

Thank you for reaching out. If I am understanding correctly, it appears that you are trying to "Extract WURFL device data file in CSV format". If so, the reason why virtual capabilities is returning NULL is due to the fact that virtual capabilities are not preset values - they are calculated during the API runtime. The non-virtual capabilities on the other hand are hard-coded values.

Hope this provides some clarity. Let me know if you have any further questions or concerns.

Thanks,

Aaron
aaronp
 
Posts: 176
Joined: Wed Dec 09, 2015 12:39 pm

Re: virtual_capability reading is giving NULL from C API cal

Postby gpatel » Wed Apr 05, 2017 10:52 am

Hi Aaronp,

Thank you so much for the quick response.

Basically our need is to extract below virtual capabilities from the wurfl.xml for every device if it present in wurfl.xml.
Could you please give some sort of C code example for extracting these virtual capabilities for every device if exist from the wurfl.xml

Code: Select all
<group id="virtual">
        <capability name="controlcap_is_smartphone" value="default"/>
        <capability name="controlcap_is_ios" value="default"/>
        <capability name="controlcap_is_android" value="default"/>
        <capability name="controlcap_is_robot" value="default"/>
        <capability name="controlcap_is_app" value="default"/>
        <capability name="controlcap_advertised_device_os" value="default"/>
        <capability name="controlcap_advertised_device_os_version" value="default"/>
        <capability name="controlcap_advertised_browser" value="default"/>
        <capability name="controlcap_advertised_browser_version" value="default"/>
        <capability name="controlcap_is_windows_phone" value="default"/>
        <capability name="controlcap_is_full_desktop" value="default"/>
        <capability name="controlcap_is_largescreen" value="default"/>
        <capability name="controlcap_is_mobile" value="default"/>
        <capability name="controlcap_is_touchscreen" value="default"/>
        <capability name="controlcap_is_wml_preferred" value="default"/>
        <capability name="controlcap_is_xhtmlmp_preferred" value="default"/>
        <capability name="controlcap_is_html_preferred" value="default"/>
        <capability name="controlcap_form_factor" value="default"/>
        <capability name="controlcap_complete_device_name" value="default"/>
        <capability name="controlcap_is_phone" value="default"/>
        <capability name="controlcap_is_app_webview" value="default"/>
        <capability name="controlcap_device_name" value="default"/>
        <capability name="controlcap_advertised_app_name" value="default"/>
 </group>


As per the link https://www.scientiamobile.com/wurflCapability it says,

advertised_browser
This virtual capability will infer the name of the browser based on user-agent string analysis (and possibly the analysis of other HTTP headers and WURFL capabilities).
advertised_browser_version
This virtual capability will infer the name of the browser based on user-agent string analysis (and possibly the analysis of other HTTP headers and WURFL capabilities).
advertised_device_os
This virtual capability will infer the name of the Device OS based on user-agent string analysis (and possibly the analysis of other HTTP headers and WURFL capabilities).
advertised_device_os_version
This virtual capability will infer the name of the Device OS Version based on user-agent string analysis (and possibly the analysis of other HTTP headers and WURFL capabilities).

So i tried the code snippet as below to extract value for each device by creating the device handle with user_agent string which have such capabilities defined in wurfl.xml, But getting always NULL return.

Code: Select all
wurfl_device_handle hvcdevice = wurfl_lookup_useragent(hwurfl, user_agent.c_str());
if(hvcdevice) {                     
    std::string advertised_device_os = wurfl_device_get_virtual_capability(hvcdevice, "controlcap_advertised_device_os");
    std::string advertised_device_os_version = wurfl_device_get_virtual_capability(hvcdevice, "controlcap_advertised_device_os_version");
    std::string advertised_browser = wurfl_device_get_virtual_capability(hvcdevice, "controlcap_advertised_browser");
    std::string advertised_browser_version = wurfl_device_get_virtual_capability(hvcdevice, "controlcap_advertised_browser_version");
    wurfl_device_destroy(hvcdevice);
}


As per your quote
the reason why virtual capabilities is returning NULL is due to the fact that virtual capabilities are not preset values - they are calculated during the API runtime.
. How we can get these virtual capabilities value for each device during the runtime API call.
Last edited by gpatel on Wed Apr 05, 2017 11:13 am, edited 1 time in total.
gpatel
 
Posts: 3
Joined: Wed Apr 05, 2017 5:38 am

Re: virtual_capability reading is giving NULL from C API cal

Postby aaronp » Wed Apr 05, 2017 11:10 am

Hi,

I see what you are saying, however, due to the way virtual capabilities work, there is no function or method to dump all possible outcomes for virtual capabilities. This is due to the fact that virtual capabilities return a value which are calculated by the API during runtime while all physical capabilities have a preset determined value.

For an example:

- device_os (regular capability) has a hard-coded value
- advertised_device_os (virtual capability)has a value that is determined by the API during real-time analysis of the user agent string.

Hope this helps. Let me know if you need any further clarifications.

Aaron
aaronp
 
Posts: 176
Joined: Wed Dec 09, 2015 12:39 pm

Re: virtual_capability reading is giving NULL from C API cal

Postby gpatel » Wed Apr 05, 2017 11:30 am

Hi Aaronp,

<device id="generic_smarttv_chromecast" user_agent="Mozilla/5.0 (CrKey armv7l 1.4.15250) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.0 Safari/537.36" fall_back="generic_smarttv_browser">
<group id="product_info">
<capability name="model_name" value="Chromecast"/>
<capability name="brand_name" value="Google"/>
<capability name="release_date" value="2013_july"/>
</group>
<group id="virtual">
<capability name="controlcap_advertised_device_os" value="Chromecast"/>
</group>
</device>

My concern is based on the above device node which i took it from the wurfl.xml, if i do the query for the "controlcap_advertised_device_os", i should get the value as "Chromecast", but its returning NULL. why?

char *user_agent = "Mozilla/5.0 (CrKey armv7l 1.4.15250) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.0 Safari/537.36"
wurfl_device_handle hvcdevice = wurfl_get_device(hwurfl, user_agent);
if(hvcdevice) {
std::string advertised_device_os = wurfl_device_get_virtual_capability(hvcdevice, "controlcap_advertised_device_os"); // returns NULL why?
wurfl_device_destroy(hvcdevice);
}
gpatel
 
Posts: 3
Joined: Wed Apr 05, 2017 5:38 am

Re: virtual_capability reading is giving NULL from C API cal

Postby aaronp » Wed Apr 05, 2017 1:10 pm

Hi,

I just noticed that your API version (1.4.4.1) is extremely outdated. The reason why NULL is being returned is because Virtual Capabilities were first introduced starting with API v1.5

Are you able to update your API to the latest release (v1.8.4.0) and let me know if you are still seeing the same issue?

Also, instead of using the controlcap (used to override values), you will want to use the actual capability - in this case you will want to use advertised_device_os

Thanks,

Aaron
aaronp
 
Posts: 176
Joined: Wed Dec 09, 2015 12:39 pm


Return to Varnish Cache, Apache, NGINX Modules and WURFL C++ API

Who is online

Users browsing this forum: No registered users and 1 guest