xref: /btstack/test/mesh/provisioning_device_test.cpp (revision 9f1d8eee3da7ea3eb34ff486475434e06110d7f9)
1 /*
2  * Copyright (C) 2017 BlueKitchen GmbH
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the copyright holders nor the names of
14  *    contributors may be used to endorse or promote products derived
15  *    from this software without specific prior written permission.
16  * 4. Any redistribution, use, or modification is done solely for
17  *    personal benefit and not for any commercial purpose or for
18  *    monetary gain.
19  *
20  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
24  * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  * Please inquire about commercial licensing options at
34  * [email protected]
35  *
36  */
37 
38 #include <stdint.h>
39 #include <stdio.h>
40 #include "btstack_memory.h"
41 #include "ble/gatt-service/mesh_provisioning_service_server.h"
42 #include "hci_dump.h"
43 #include "mesh/mesh_node.h"
44 #include "mesh/pb_adv.h"
45 #include "mesh/pb_gatt.h"
46 #include "mesh/provisioning.h"
47 #include "mesh/provisioning_device.h"
48 
49 #include "CppUTest/TestHarness.h"
50 #include "CppUTest/CommandLineTestRunner.h"
51 
52 #include "mock.h"
53 
54 static void CHECK_EQUAL_ARRAY(const char * name, uint8_t * expected, uint8_t * actual, int size){
55     int i;
56     for (i=0; i<size; i++){
57         if (expected[i] != actual[i]) {
58             printf("%s: offset %u wrong\n", name, i);
59             printf("expected: "); printf_hexdump(expected, size);
60             printf("actual:   "); printf_hexdump(actual, size);
61         }
62         BYTES_EQUAL(expected[i], actual[i]);
63     }
64 }
65 
66 const static uint8_t device_uuid[] = { 0x00, 0x1B, 0xDC, 0x08, 0x10, 0x21, 0x0B, 0x0E, 0x0A, 0x0C, 0x00, 0x0B, 0x0E, 0x0A, 0x0C, 0x00 };
67 
68 // pb-adv mock for testing
69 
70 static btstack_packet_handler_t pb_adv_packet_handler;
71 
72 static uint8_t * pdu_data;
73 static uint16_t  pdu_size;
74 
75 /**
76  * Initialize Provisioning Bearer using Advertisement Bearer
77  * @param DeviceUUID
78  */
79 void pb_adv_init(void){}
80 void pb_gatt_init(void){}
81 
82 /**
83  * Close Link
84  * @param con_handle
85  * @param reason 0 = success, 1 = timeout, 2 = fail
86  */
87 void pb_gatt_close_link(hci_con_handle_t con_handle, uint8_t reason){
88     UNUSED(con_handle);
89     UNUSED(reason);
90 }
91 void pb_adv_close_link(hci_con_handle_t con_handle, uint8_t reason){
92     UNUSED(con_handle);
93     UNUSED(reason);
94 }
95 
96 
97 /**
98  * Register listener for Provisioning PDUs and MESH_PBV_ADV_SEND_COMPLETE
99  */
100 void pb_adv_register_device_packet_handler(btstack_packet_handler_t packet_handler){
101     pb_adv_packet_handler = packet_handler;
102 }
103 
104 void pb_gatt_register_packet_handler(btstack_packet_handler_t packet_handler){
105     UNUSED(packet_handler);
106 }
107 /**
108  * Send Provisioning PDU
109  */
110 void pb_adv_send_pdu(uint16_t pb_transport_cid, const uint8_t * pdu, uint16_t size){
111     UNUSED(pb_transport_cid);
112     pdu_data = (uint8_t*) pdu;
113     pdu_size = size;
114     // dump_data((uint8_t*)pdu,size);
115     // printf_hexdump(pdu, size);
116 }
117 void pb_gatt_send_pdu(uint16_t con_handle, const uint8_t * pdu, uint16_t _pdu_size){
118     UNUSED(con_handle);
119     UNUSED(pdu);
120     UNUSED(_pdu_size);
121 }
122 
123 uint16_t mesh_network_key_get_free_index(void){
124     return 0;
125 }
126 
127 static mesh_network_key_t network_key;
128 extern "C" mesh_network_key_t * btstack_memory_mesh_network_key_get(void){
129     return &network_key;
130 }
131 
132 static void perform_crypto_operations(void){
133     int more = 1;
134     while (more){
135         more = mock_process_hci_cmd();
136     }
137 }
138 
139 static void send_prov_pdu(const uint8_t * packet, uint16_t size){
140     pb_adv_packet_handler(PROVISIONING_DATA_PACKET, 0, (uint8_t*) packet, size);
141     perform_crypto_operations();
142 }
143 
144 static void pb_adv_emit_pdu_sent(uint8_t status){
145     uint8_t event[] = { HCI_EVENT_MESH_META, 2, MESH_SUBEVENT_PB_TRANSPORT_PDU_SENT, status};
146     pb_adv_packet_handler(HCI_EVENT_PACKET, 0, event, sizeof(event));
147 }
148 
149 static int scan_hex_byte(const char * byte_string){
150     int upper_nibble = nibble_for_char(*byte_string++);
151     if (upper_nibble < 0) return -1;
152     int lower_nibble = nibble_for_char(*byte_string);
153     if (lower_nibble < 0) return -1;
154     return (upper_nibble << 4) | lower_nibble;
155 }
156 
157 static int btstack_parse_hex(const char * string, uint16_t len, uint8_t * buffer){
158     int i;
159     for (i = 0; i < len; i++) {
160         int single_byte = scan_hex_byte(string);
161         if (single_byte < 0) return 0;
162         string += 2;
163         buffer[i] = (uint8_t)single_byte;
164         // don't check seperator after last byte
165         if (i == len - 1) {
166             return 1;
167         }
168         // optional seperator
169         char separator = *string;
170         if (separator == ':' && separator == '-' && separator == ' ') {
171             string++;
172         }
173     }
174     return 1;
175 }
176 
177 // void pb_gatt_close_link(hci_con_handle_t con_handle, uint8_t reason){
178 // }
179 
180 static uint8_t      prov_static_oob_data[16];
181 static const char * prov_static_oob_string = "00000000000000000102030405060708";
182 
183 TEST_GROUP(Provisioning){
184     void setup(void){
185         mock_init();
186         for (unsigned int i = 0 ; i < 4 ; i ++){
187             printf("rand: %08x\n", rand());
188         }
189         btstack_crypto_init();
190         provisioning_device_init();
191         mesh_node_set_device_uuid(device_uuid);
192         btstack_parse_hex(prov_static_oob_string, 16, prov_static_oob_data);
193         provisioning_device_set_static_oob(16, prov_static_oob_data);
194         provisioning_device_set_output_oob_actions(0x08, 0x08);
195         provisioning_device_set_input_oob_actions(0x08, 0x08);
196         perform_crypto_operations();
197     }
198 };
199 
200 uint8_t prov_invite[] = { 0x00, 0x00 };
201 uint8_t prov_capabilities[] = { 0x01, 0x01, 0x00, 0x01, 0x00, 0x01, 0x08, 0x00, 0x08, 0x08, 0x00, 0x08, };
202 uint8_t prov_start[] = { 0x02, 0x00, 0x00, 0x02, 0x00, 0x01 };
203 uint8_t prov_public_key[] = { 0x03,
204                               0x8E, 0x9D, 0xEE, 0x76, 0x17, 0x67, 0x4A, 0xCD, 0xBE, 0xA5, 0x4D, 0xCD, 0xAB, 0x7E, 0xA3, 0x83,
205                               0x26, 0xF6, 0x87, 0x22, 0x7F, 0x97, 0xE7, 0xC4, 0xEE, 0xF5, 0x2F, 0x7C, 0x80, 0x5A, 0xEB, 0x2A,
206                               0x59, 0x46, 0x99, 0xDF, 0x60, 0x54, 0x53, 0x47, 0x48, 0xF8, 0xA1, 0x99, 0xF0, 0x02, 0xE7, 0x23,
207                               0x2C, 0x52, 0x9C, 0xBA, 0x0F, 0x54, 0x94, 0x1F, 0xE4, 0xB7, 0x02, 0x89, 0x9E, 0x03, 0xFA, 0x43 };
208 uint8_t prov_confirm[] = { 0x05,
209                            0x5F, 0xDE, 0x98, 0x35, 0x7F, 0x0B, 0xA2, 0xB2, 0x94, 0x72, 0x03, 0xD6, 0x82, 0x57, 0xF0, 0x6E };
210 uint8_t prov_random[]  = { 0x06, 0xC2, 0xE1, 0xF1, 0xF9, 0x7D, 0x3F, 0x9E, 0xCF, 0xE6, 0x73, 0xB8, 0x5C, 0x2E, 0x97, 0x4A, 0x25, };
211 uint8_t prov_data[] = {
212     0x07,
213     0x85, 0x66, 0xac, 0x46, 0x37, 0x34, 0x86, 0xe1, 0x3e, 0x4c, 0x13, 0x52, 0xd0, 0x6d, 0x34, 0x7d,
214     0xce, 0xf1, 0xd1, 0x7d, 0xbd, 0xbe, 0xcc, 0x99, 0xc3,
215     0x93, 0x87, 0xfc, 0xb0, 0x72, 0x0f, 0xd8, 0x8d };
216 uint8_t prov_complete[] = { 0x08, };
217 
218 TEST(Provisioning, Prov1){
219     // send prov inviate
220     send_prov_pdu(prov_invite, sizeof(prov_invite));
221     // check for prov cap
222     CHECK_EQUAL_ARRAY("prov_capabilities", prov_capabilities, pdu_data, sizeof(prov_capabilities));
223     pb_adv_emit_pdu_sent(0);
224     // send prov start
225     send_prov_pdu(prov_start, sizeof(prov_start));
226     // send public key
227     send_prov_pdu(prov_public_key, sizeof(prov_public_key));
228     // check for public key
229     CHECK_EQUAL_ARRAY("prov_public_key", prov_public_key, pdu_data, sizeof(prov_public_key));
230     pb_adv_emit_pdu_sent(0);
231     // send prov confirm
232     send_prov_pdu(prov_confirm, sizeof(prov_confirm));
233     // check for prov confirm
234     CHECK_EQUAL_ARRAY("prov_confirm", prov_confirm, pdu_data, sizeof(prov_confirm));
235     pb_adv_emit_pdu_sent(0);
236     // send prov random
237     send_prov_pdu(prov_random, sizeof(prov_random));
238     // check for prov random
239     CHECK_EQUAL_ARRAY("prov_random", prov_random, pdu_data, sizeof(prov_random));
240     pb_adv_emit_pdu_sent(0);
241     // send prov data
242     send_prov_pdu(prov_data, sizeof(prov_data));
243     // check prov complete
244     CHECK_EQUAL_ARRAY("prov_complete", prov_complete, pdu_data, sizeof(prov_complete));
245     pb_adv_emit_pdu_sent(0);
246 }
247 
248 int main (int argc, const char * argv[]){
249     hci_dump_open("hci_dump.pklg", HCI_DUMP_PACKETLOGGER);
250     return CommandLineTestRunner::RunAllTests(argc, argv);
251 }
252