# 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=<path to the pcre library>
- PCRE_INCLUDE_DIR=<path to the pcre headers folder>
(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=<full path to the C compiler executable>
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
// 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 _