# DeviceAtlas Device Detection API # The DeviceAtlas Device Detection API provides a way to detect devices based on the User-Agent HTTP header. Using this header, the API returns device information such as screen width, screen height, is mobile, vendor, model etc. To see a full list of properties in DeviceAtlas please visit: https://deviceatlas.com/resources/available-properties . ### Data File ### The DeviceAtlas API relies on a device data file to function. DeviceAtlas provides daily data file updates so it is recommended to download the data file on a regular basis. This can be done manually from your account page or automated via the https://deviceatlas.com/getJSON page. For more information please see: https://deviceatlas.com/resources/getting-the-data ### Pre-Requirements ### - A C compiler - CMake 2.6 (or above) Following compilers have been tested and are able to compile all components: - GCC (3.4 or above (4.x versions are recommended)) ** - Clang/LLVM (3.0 or above) ** - Sun Pro family (12.x or above) ### CMake ### CMake should be able to find out all necessary components if you installed them through your package manager. ** PCRE library and headers ** If your PCRE library and headers are located in custom locations it is possible to set these cmake environment variables: - PCRELIB=&lt;path to the pcre library&gt; - PCRE_INCLUDE_DIR=&lt;path to the pcre headers folder&gt; (e.g. Red Hat based operating systems, the needed packages are pcre-devel; for Debian, the names are libpcre3-dev; otherwise, please check pcre and zlib development packages with your package manager). For example: ```shell cmake -DPCRELIB=/home/test/pcre/lib/libpcre.so -DPCRE_INCLUDE_DIR=/home/test/pcre/include ``` Compatibility: For older PCRE versions it is possible to disable PCRE Study feature with cmake -DPCRE_STUDY=0. It is highly recommended to do NOT disable PCRE Study for better performance. ** Custom compiler location ** - CMAKE_C_COMPILER=&lt;full path to the C compiler executable&gt; For example: ```shell cmake -DCMAKE_C_COMPILER=/home/test/gcc-4.8.3/bin/gcc -DCMAKE_CXX_COMPILER=/home/test/gcc-4.8.3/bin/g++ ``` NB: For a static API version used with another shared library it is possible to use CFLAGS/CXXFLAGS with -fPIC/fpic compilation flag. ### Building the API ### 1. Unpack the API 2. Change to the API directory 3. Run cmake command. 4. Run make. ```shell % cmake . % make ``` ### Basic Usage ### #### Example 1 #### The following example code shows the API loading the data file and using a property name to find a certain value for a given User-Agent. ```c #include <dac.h> // The 2 functions below are necessary for da_atlas_compile // as it needs 2 function pointers for reading and seeking in the data file static size_t filereader(void *ctx, size_t count, char *buf) { return fread(buf, 1, count, ctx); } static da_status_t fileseeker(void *ctx, off_t pos) { return fseek(ctx, pos, SEEK_SET) != -1 ? DA_OK : DA_SYS; } ... da_atlas_t atlas; da_status_t status; void *ptr; size_t size; const char *jsonpath = argv[1]; const char *useragent = argv[2]; // Json file reading FILE *json = fopen(jsonpath, "r"); if (!json) { fprintf(stderr, "fread failed: %s\n", jsonpath); exit(EXIT_FAILURE); } da_init(); if ((status = da_atlas_compile(json, filereader, fileseeker, &ptr, &size)) != DA_OK) { fprintf(stderr, "da_atlas_compile failed\n"); goto dafini; } da_property_decl_t extraprops[] = {{ 0, 0 }}; if ((status = da_atlas_open(&atlas, extraprops, ptr, size)) != DA_OK) { fprintf(stderr, "da_atlas_open failed\n"); goto daclose; } da_evidence_id_t useragentid = da_atlas_evidence_id(&atlas, "user-agent"); da_evidence_t headers[1] = {{ useragentid, useragent }}; da_deviceinfo_t device; // it exists an alternative variadic version call ... // da_search(&atlas, &device, headers[0].key, headers[0].value, 0); if ((status = da_searchv(&atlas, &device, headers, 1)) != DA_OK) { fprintf(stderr, "da_search failed\n"); goto daclose; } da_propid_t *prop; // da_getfirstprop / da_getnextprop are convenient way to iterate through the properties list // alternatively, it is possible to know the number of properties via da_deviceinfo_t's propcount field for (status = da_getfirstprop(&device, &prop); status == DA_OK; status = da_getnextprop(&device, &prop)) { const char *name; da_type_t type; da_getpropname(&device, *prop, &name); da_getproptype(&device, *prop, &type); char buf[256]; switch (type) { case DA_TYPE_INTEGER: { long val; da_getpropinteger(&device, *prop, &val); sprintf(buf, "%ld", val); break; } case DA_TYPE_BOOLEAN: { bool val; da_getpropboolean(&device, *prop, &val); sprintf(buf, "%d", val); } case DA_TYPE_STRING: { const char *val; da_getpropstring(&device, *prop, &val); size_t vallen = min(strlen(val), sizeof(buf) - 1); strncpy(buf, val, vallen); buf[vallen] = 0; break; } default: break; } da_close(&device); daclose: da_atlas_close(&atlas); free(ptr); dafini: da_fini(); ``` ### Sample applications ### There are multiple examples in the /examples folder to test the API. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - _ (c) 2008-2021 DeviceAtlas Limited. All rights reserved. https://deviceatlas.com _ <!-- HTML+JS for document formatting when opened in browser --> <div class="btn-group" id="main-menu" style="float:right"><a class="btn dropdown-toggle" data-toggle="dropdown" href="#">Menu<span class="caret"></span></a><ul class="dropdown-menu"><li><a href="README.html">Main</a></li><li class="divider"></li><li class="disabled"><a href="README.DeviceApi.html">Device Detection API</a></li><li><a href="README.ClientSide.html">Client-side Component</a></li><li class="divider"></li><li><a href="ApiDocs/index.html">DeviceAtlas ApiDocs</a></li></ul></div>