summaryrefslogtreecommitdiff
path: root/code/esp32/components/eos/at_urc.c
blob: b362d6fc7d5ceb93c613db0c7a9df4394b7aa9f5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include <stdlib.h>
#include <string.h>

#include <freertos/FreeRTOS.h>
#include <freertos/semphr.h>

#include "eos.h"
#include "at_urc.h"

typedef struct ATURCItem {
    regex_t re;
    at_urc_cb_t cb;
    char pattern[AT_SIZE_PATTERN];
} ATURCItem;

typedef struct ATURCList {
    ATURCItem item[AT_SIZE_URC_LIST];
    int len;
} ATURCList;

static ATURCList urc_list;
static ATURCItem *urc_curr;
static SemaphoreHandle_t mutex;

int at_urc_process(char *urc) {
    regmatch_t match[AT_SIZE_NMATCH];
    at_urc_cb_t cb = NULL;
    regmatch_t *m = NULL;

    xSemaphoreTake(mutex, portMAX_DELAY);

    if (urc_curr == NULL) {
        int i;

        for (i=0; i<urc_list.len; i++) {
            if (regexec(&urc_list.item[i].re, urc, AT_SIZE_NMATCH, match, 0) == 0) {
                urc_curr = &urc_list.item[i];
                m = match;
                break;
            }
        }
    }
    if (urc_curr) cb = urc_curr->cb;

    xSemaphoreGive(mutex);

    if (cb) {
        int r = cb(urc, m);

        if (r != AT_URC_MORE) {
            xSemaphoreTake(mutex, portMAX_DELAY);
            urc_curr = NULL;
            xSemaphoreGive(mutex);
        }
        return 1;
    }
    return 0;
}

int at_urc_insert(char *pattern, at_urc_cb_t cb, int flags) {
    int r = EOS_OK;

    if (strlen(pattern) >= AT_SIZE_PATTERN) return EOS_ERR;

    r = regcomp(&urc_list.item[urc_list.len].re, pattern, flags);
    if (r) return EOS_ERR;

    xSemaphoreTake(mutex, portMAX_DELAY);

    if (urc_list.len == AT_SIZE_URC_LIST) r = EOS_ERR_FULL;

    if (!r) {
        strcpy(urc_list.item[urc_list.len].pattern, pattern);
        urc_list.item[urc_list.len].cb = cb;
        urc_list.len++;
    }

    xSemaphoreGive(mutex);

    return r;
}

int at_urc_delete(char *pattern) {
    int i;
    int r = EOS_ERR_NOTFOUND;

    xSemaphoreTake(mutex, portMAX_DELAY);

    for (i=0; i<urc_list.len; i++) {
        if ((strcmp(pattern, urc_list.item[i].pattern) == 0)) {
            if (i != urc_list.len - 1) memmove(&urc_list.item[i], &urc_list.item[i + 1], (urc_list.len - i - 1) * sizeof(ATURCItem));
            urc_list.len--;
            if (urc_curr) {
                if (urc_curr == &urc_list.item[i]) {
                    urc_curr = NULL;
                } else if (urc_curr > &urc_list.item[i]) {
                    urc_curr--;
                }
            }

            r = EOS_OK;
            break;
        }
    }

    xSemaphoreGive(mutex);

    return r;
}