# DeviceAtlas Device Detection API # The DeviceAtlas Device Detection API provides a way to detect devices based on the data found in HTTP headers. Using these headers, 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 ### Requirements ### - A C compiler - CMake 2.6 (or above) - PCRE 6.x (or above). For best performance v8.21 (or above) is recommended. **Important** - There are two major versions of the PCRE library: PCRE and PCRE2. PCRE2 is not compatible and should not be used. The 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 ### By default CMake should find all necessary components if they are installed with a package manager. This section describes setting cmake variables to handle components installed in custom locations. ** PCRE library and headers ** If the PCRE library and headers are located in a custom location, the following cmake environment variables may be set: - PCRELIB=&lt;path to the pcre library&gt; - PCRE_INCLUDE_DIR=&lt;path to the pcre headers folder&gt; (For Red Hat based operating systems, the required 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. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - _ Copyright (c) DeviceAtlas Limited 2021. 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 class="divider"></li><li><a href="README.Windows.html">C API and Windows</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>