WXK
2025-01-21 8f1a91a8ec98e430cfe4357bda099d495917198e
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
/**
 *******************************************************************************
 * @file     gw.c
 * @create   2023-08-01
 * @author   Panchip BLE GROUP
 * @note
 * Copyright (c) 2022 Shanghai Panchip Microelectronics Co.,Ltd.
 *
 *******************************************************************************
 */
#include "gw.h"
#include "host/ble_hs.h"
#include "app_log.h"
 
uint16_t gwRxValHandle;
uint16_t gwTxValHandle;
 
static uint8_t gwRxVal[64];
 
extern void app_ble_rx(uint16_t connHandle, struct os_mbuf *om);
 
__WEAK void app_ble_rx(uint16_t connHandle, struct os_mbuf *om)
{
    //printf("Rx data 1(handle:%d):\r\n", *ctxt->chr->val_handle);
    //print_data(ctxt->om->om_data, ctxt->om->om_len);
    //memcpy(gwRxVal, ctxt->om->om_data, min(ctxt->om->om_len, sizeof(gwRxVal)));
}
 
int ble_svc_gw_access(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg);
int ble_svc_gw_dsc_access(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg);
 
static const struct ble_gatt_svc_def ble_svc_gw_defs[] =
{
    /*** GW Service. */
    {
        .type = BLE_GATT_SVC_TYPE_PRIMARY,
        .uuid = BLE_UUID128_DECLARE(BLE_SVC_GW_UUI128),
        .characteristics = (struct ble_gatt_chr_def[])
        {
            /*** GW RX characteristic */
            {
                .uuid = BLE_UUID128_DECLARE(BLE_SVC_GW_CHR_UUID128_RX),
                .access_cb = ble_svc_gw_access,
                .val_handle = (uint16_t *)&gwRxValHandle,
                .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE_NO_RSP,
                .descriptors = (struct ble_gatt_dsc_def[])
                {
                    {
                        .uuid = BLE_UUID16_DECLARE(BLE_GATT_USR_DSC_CHR_UUID16),
                        .att_flags = BLE_ATT_F_READ,
                        .access_cb = ble_svc_gw_access,
                    },
                    {
                        0, /* No more descriptors in this characteristic. */
                    }
                }
            },
 
            /*** GW TX characteristic */
            {
                .uuid = BLE_UUID128_DECLARE(BLE_SVC_GW_CHR_UUID128_TX),
                .access_cb = ble_svc_gw_access,
                .val_handle = (uint16_t *)&gwTxValHandle,
                .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_NOTIFY,
                .descriptors = (struct ble_gatt_dsc_def[])
                {
                    {
                        .uuid = BLE_UUID16_DECLARE(BLE_GATT_USR_DSC_CHR_UUID16),
                        .att_flags = BLE_ATT_F_READ,
                        .access_cb = ble_svc_gw_access,
                    },
                    {
                        0, /* No more descriptors in this characteristic. */
                    }
                }
            },
 
            /* No more characteristics in this service. */
            {
                0,
            }
        },
    },
 
    /* No more services. */
    {
        0,
    },
};
 
int ble_svc_gw_access(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt, void *arg)
{
    int rc = 0;
 
    switch(ctxt->op)
    {
    case BLE_GATT_ACCESS_OP_READ_CHR:
        if(attr_handle == gwRxValHandle) {
            rc = os_mbuf_append(ctxt->om, &gwRxVal[0], sizeof gwRxVal);
        }
        return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
 
    case BLE_GATT_ACCESS_OP_WRITE_CHR:
        if(attr_handle == gwRxValHandle) {
            app_ble_rx(conn_handle, ctxt->om);
        }
        return 0;
        
    case BLE_GATT_ACCESS_OP_READ_DSC:
        if(attr_handle == gwRxValHandle+1)
        {
            char *str = "Rx Data";
            os_mbuf_append(ctxt->om, str, strlen(str));
        }
        else if(attr_handle == gwTxValHandle+2)
        {
            char *str = "Tx Data";
            os_mbuf_append(ctxt->om, str, strlen(str));
        }
        break;
    
    case BLE_GATT_ACCESS_OP_WRITE_DSC:
        return BLE_ATT_ERR_INVALID_PDU;
 
    default:
        return 0;
    }
    
    return 0;
}
 
int ble_svc_gw_notify(uint16_t conn_handle, uint8_t *pdata, uint32_t len)
{
    int rc = 0;
 
    struct os_mbuf *om = ble_hs_mbuf_from_flat(pdata, len);
    if(om)
    {
        rc = ble_gatts_notify_custom(conn_handle, gwTxValHandle, om);
    }
    else{
        rc = BLE_NPL_ENOMEM;
    }
 
    return rc;
}
 
 
int  ble_svc_gw_init(void)
{
    int rc;
 
    rc = ble_gatts_count_cfg(ble_svc_gw_defs);
    app_assert(rc == 0);
 
    rc = ble_gatts_add_svcs(ble_svc_gw_defs);
    app_assert(rc == 0);
 
    return rc;
}