xref: /btstack/test/hfp/mock.c (revision dc5611fddefa948cedb447d9bfd1d551e6e657f0)
1*dc5611fdSMilanka Ringwald /*
2*dc5611fdSMilanka Ringwald  * Copyright (C) 2014 BlueKitchen GmbH
3*dc5611fdSMilanka Ringwald  *
4*dc5611fdSMilanka Ringwald  * Redistribution and use in source and binary forms, with or without
5*dc5611fdSMilanka Ringwald  * modification, are permitted provided that the following conditions
6*dc5611fdSMilanka Ringwald  * are met:
7*dc5611fdSMilanka Ringwald  *
8*dc5611fdSMilanka Ringwald  * 1. Redistributions of source code must retain the above copyright
9*dc5611fdSMilanka Ringwald  *    notice, this list of conditions and the following disclaimer.
10*dc5611fdSMilanka Ringwald  * 2. Redistributions in binary form must reproduce the above copyright
11*dc5611fdSMilanka Ringwald  *    notice, this list of conditions and the following disclaimer in the
12*dc5611fdSMilanka Ringwald  *    documentation and/or other materials provided with the distribution.
13*dc5611fdSMilanka Ringwald  * 3. Neither the name of the copyright holders nor the names of
14*dc5611fdSMilanka Ringwald  *    contributors may be used to endorse or promote products derived
15*dc5611fdSMilanka Ringwald  *    from this software without specific prior written permission.
16*dc5611fdSMilanka Ringwald  * 4. Any redistribution, use, or modification is done solely for
17*dc5611fdSMilanka Ringwald  *    personal benefit and not for any commercial purpose or for
18*dc5611fdSMilanka Ringwald  *    monetary gain.
19*dc5611fdSMilanka Ringwald  *
20*dc5611fdSMilanka Ringwald  * THIS SOFTWARE IS PROVIDED BY BLUEKITCHEN GMBH AND CONTRIBUTORS
21*dc5611fdSMilanka Ringwald  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22*dc5611fdSMilanka Ringwald  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23*dc5611fdSMilanka Ringwald  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTHIAS
24*dc5611fdSMilanka Ringwald  * RINGWALD OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25*dc5611fdSMilanka Ringwald  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26*dc5611fdSMilanka Ringwald  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27*dc5611fdSMilanka Ringwald  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28*dc5611fdSMilanka Ringwald  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29*dc5611fdSMilanka Ringwald  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
30*dc5611fdSMilanka Ringwald  * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31*dc5611fdSMilanka Ringwald  * SUCH DAMAGE.
32*dc5611fdSMilanka Ringwald  *
33*dc5611fdSMilanka Ringwald  * Please inquire about commercial licensing options at
34*dc5611fdSMilanka Ringwald  * [email protected]
35*dc5611fdSMilanka Ringwald  *
36*dc5611fdSMilanka Ringwald  */
37*dc5611fdSMilanka Ringwald 
38*dc5611fdSMilanka Ringwald // *****************************************************************************
39*dc5611fdSMilanka Ringwald //
40*dc5611fdSMilanka Ringwald // HFP BTstack Mocks
41*dc5611fdSMilanka Ringwald //
42*dc5611fdSMilanka Ringwald // *****************************************************************************
43*dc5611fdSMilanka Ringwald 
4412381011SMilanka Ringwald #include <stdint.h>
4512381011SMilanka Ringwald #include <stdio.h>
4612381011SMilanka Ringwald #include <stdlib.h>
4712381011SMilanka Ringwald #include <string.h>
4812381011SMilanka Ringwald 
4912381011SMilanka Ringwald #include <btstack/btstack.h>
5012381011SMilanka Ringwald #include "hci.h"
5112381011SMilanka Ringwald #include "hci_dump.h"
5212381011SMilanka Ringwald #include "sdp_query_rfcomm.h"
5312381011SMilanka Ringwald #include "rfcomm.h"
54*dc5611fdSMilanka Ringwald #include "hfp_hf.h"
55*dc5611fdSMilanka Ringwald 
56*dc5611fdSMilanka Ringwald #include "mock.h"
5712381011SMilanka Ringwald 
5812381011SMilanka Ringwald static void *registered_sdp_app_context;
5912381011SMilanka Ringwald static uint8_t sdp_rfcomm_channel_nr = 1;
6012381011SMilanka Ringwald const char sdp_rfcomm_service_name[] = "BTstackMock";
6112381011SMilanka Ringwald static uint16_t rfcomm_cid = 1;
6212381011SMilanka Ringwald static uint8_t rfcomm_payload[200];
6312381011SMilanka Ringwald static uint16_t rfcomm_payload_len;
6412381011SMilanka Ringwald void * active_connection;
6512381011SMilanka Ringwald 
6612381011SMilanka Ringwald void (*registered_rfcomm_packet_handler)(void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
6712381011SMilanka Ringwald void (*registered_sdp_app_callback)(sdp_query_event_t * event, void * context);
6812381011SMilanka Ringwald 
6912381011SMilanka Ringwald uint8_t * get_rfcomm_payload(){
7012381011SMilanka Ringwald 	return &rfcomm_payload[0];
7112381011SMilanka Ringwald }
7212381011SMilanka Ringwald 
7312381011SMilanka Ringwald uint16_t get_rfcomm_payload_len(){
7412381011SMilanka Ringwald 	return rfcomm_payload_len;
7512381011SMilanka Ringwald }
7612381011SMilanka Ringwald 
77fc6b77dcSMilanka Ringwald static void prepare_rfcomm_buffer(uint8_t * data, int len){
7812381011SMilanka Ringwald 	memset(&rfcomm_payload, 0, 200);
79fc6b77dcSMilanka Ringwald 	int pos = 0;
80fc6b77dcSMilanka Ringwald 	if (memcmp((char*)data, "AT", 2) != 0){
81fc6b77dcSMilanka Ringwald 		rfcomm_payload[pos++] = '\r';
82fc6b77dcSMilanka Ringwald 		rfcomm_payload[pos++] = '\n';
83fc6b77dcSMilanka Ringwald 	}
84fc6b77dcSMilanka Ringwald 	memcpy((char*)&rfcomm_payload[pos], data, len);
85fc6b77dcSMilanka Ringwald 	pos += len;
86fc6b77dcSMilanka Ringwald 	if (memcmp((char*)data, "AT", 2) != 0){
87fc6b77dcSMilanka Ringwald 		rfcomm_payload[pos++] = '\r';
88*dc5611fdSMilanka Ringwald 		rfcomm_payload[pos++] = '\n';
89*dc5611fdSMilanka Ringwald         rfcomm_payload[pos++] = 'O';
90*dc5611fdSMilanka Ringwald         rfcomm_payload[pos++] = 'K';
91fc6b77dcSMilanka Ringwald     }
92*dc5611fdSMilanka Ringwald     rfcomm_payload[pos++] = '\r';
93*dc5611fdSMilanka Ringwald     rfcomm_payload[pos] = '\n';
94fc6b77dcSMilanka Ringwald 	rfcomm_payload_len = pos;
95fc6b77dcSMilanka Ringwald }
96fc6b77dcSMilanka Ringwald 
97fc6b77dcSMilanka Ringwald 
9812381011SMilanka Ringwald int  rfcomm_send_internal(uint16_t rfcomm_cid, uint8_t *data, uint16_t len){
99fc6b77dcSMilanka Ringwald 	if (memcmp((char*)data, "AT", 2) == 0){
100fc6b77dcSMilanka Ringwald 		printf("HF send: %s", data);
101fc6b77dcSMilanka Ringwald 	} else {
102fc6b77dcSMilanka Ringwald 		printf("AG send: %s", data);
103fc6b77dcSMilanka Ringwald 	}
104fc6b77dcSMilanka Ringwald 	prepare_rfcomm_buffer(data, len);
10512381011SMilanka Ringwald 	return 0;
10612381011SMilanka Ringwald }
10712381011SMilanka Ringwald 
10812381011SMilanka Ringwald int hci_send_cmd(const hci_cmd_t *cmd, ...){
10912381011SMilanka Ringwald 	printf("hci_send_cmd opcode 0x%02x\n", cmd->opcode);
11012381011SMilanka Ringwald 	return 0;
11112381011SMilanka Ringwald }
11212381011SMilanka Ringwald 
11312381011SMilanka Ringwald 
11412381011SMilanka Ringwald void sdp_query_rfcomm_register_callback(void(*sdp_app_callback)(sdp_query_event_t * event, void * context), void * context){
11512381011SMilanka Ringwald 	registered_sdp_app_callback = sdp_app_callback;
11612381011SMilanka Ringwald 	registered_sdp_app_context = context;
11712381011SMilanka Ringwald }
11812381011SMilanka Ringwald 
11912381011SMilanka Ringwald static void sdp_query_complete_response(uint8_t status){
12012381011SMilanka Ringwald     sdp_query_complete_event_t complete_event = {
12112381011SMilanka Ringwald         SDP_QUERY_COMPLETE,
12212381011SMilanka Ringwald         status
12312381011SMilanka Ringwald     };
12412381011SMilanka Ringwald     (*registered_sdp_app_callback)((sdp_query_event_t*)&complete_event, registered_sdp_app_context);
12512381011SMilanka Ringwald }
12612381011SMilanka Ringwald 
12712381011SMilanka Ringwald static void sdp_query_rfcomm_service_response(uint8_t status){
12812381011SMilanka Ringwald     sdp_query_rfcomm_service_event_t service_event = {
12912381011SMilanka Ringwald         SDP_QUERY_RFCOMM_SERVICE,
13012381011SMilanka Ringwald         sdp_rfcomm_channel_nr,
13112381011SMilanka Ringwald         (uint8_t *)sdp_rfcomm_service_name
13212381011SMilanka Ringwald     };
13312381011SMilanka Ringwald     (*registered_sdp_app_callback)((sdp_query_event_t*)&service_event, registered_sdp_app_context);
13412381011SMilanka Ringwald }
13512381011SMilanka Ringwald 
13612381011SMilanka Ringwald void sdp_query_rfcomm_channel_and_name_for_uuid(bd_addr_t remote, uint16_t uuid){
13712381011SMilanka Ringwald 	// printf("sdp_query_rfcomm_channel_and_name_for_uuid %p\n", registered_sdp_app_callback);
13812381011SMilanka Ringwald 	sdp_query_rfcomm_service_response(0);
13912381011SMilanka Ringwald 	sdp_query_complete_response(0);
14012381011SMilanka Ringwald }
14112381011SMilanka Ringwald 
14212381011SMilanka Ringwald void rfcomm_create_channel_internal(void * connection, bd_addr_t addr, uint8_t channel){
14312381011SMilanka Ringwald 	// RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE
14412381011SMilanka Ringwald 	// printf("rfcomm_create_channel_internal\n");
14512381011SMilanka Ringwald 	active_connection = connection;
14612381011SMilanka Ringwald     uint8_t event[16];
14712381011SMilanka Ringwald     uint8_t pos = 0;
14812381011SMilanka Ringwald     event[pos++] = RFCOMM_EVENT_OPEN_CHANNEL_COMPLETE;
14912381011SMilanka Ringwald     event[pos++] = sizeof(event) - 2;
15012381011SMilanka Ringwald     event[pos++] = 0;
15112381011SMilanka Ringwald 
15212381011SMilanka Ringwald     bt_flip_addr(&event[pos], addr); pos += 6;
15312381011SMilanka Ringwald     bt_store_16(event,  pos, 1);   pos += 2;
15412381011SMilanka Ringwald 	event[pos++] = 0;
15512381011SMilanka Ringwald 
15612381011SMilanka Ringwald 	bt_store_16(event, pos, rfcomm_cid); pos += 2;       // channel ID
15712381011SMilanka Ringwald 	bt_store_16(event, pos, 200); pos += 2;   // max frame size
15812381011SMilanka Ringwald     (*registered_rfcomm_packet_handler)(connection, HCI_EVENT_PACKET, 0, (uint8_t *) event, pos);
15912381011SMilanka Ringwald }
16012381011SMilanka Ringwald 
161d86bb743SMilanka Ringwald int rfcomm_can_send_packet_now(uint16_t rfcomm_cid){
162d86bb743SMilanka Ringwald 	return 1;
163d86bb743SMilanka Ringwald }
16412381011SMilanka Ringwald 
16512381011SMilanka Ringwald void rfcomm_disconnect_internal(uint16_t rfcomm_cid){
1669280a6ccSMilanka Ringwald 	uint8_t event[4];
1679280a6ccSMilanka Ringwald 	event[0] = RFCOMM_EVENT_CHANNEL_CLOSED;
1689280a6ccSMilanka Ringwald     event[1] = sizeof(event) - 2;
1699280a6ccSMilanka Ringwald     bt_store_16(event, 2, rfcomm_cid);
1709280a6ccSMilanka Ringwald     (*registered_rfcomm_packet_handler)(active_connection, HCI_EVENT_PACKET, 0, (uint8_t *) event, sizeof(event));
17112381011SMilanka Ringwald }
17212381011SMilanka Ringwald 
17312381011SMilanka Ringwald void rfcomm_register_packet_handler(void (*handler)(void * connection, uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size)){
17412381011SMilanka Ringwald 	registered_rfcomm_packet_handler = handler;
17512381011SMilanka Ringwald }
17612381011SMilanka Ringwald 
17712381011SMilanka Ringwald void rfcomm_register_service_internal(void * connection, uint8_t channel, uint16_t max_frame_size){
17812381011SMilanka Ringwald 	printf("rfcomm_register_service_internal\n");
17912381011SMilanka Ringwald }
18012381011SMilanka Ringwald 
18112381011SMilanka Ringwald 
18212381011SMilanka Ringwald void sdp_query_rfcomm_channel_and_name_for_search_pattern(bd_addr_t remote, uint8_t * des_serviceSearchPattern){
18312381011SMilanka Ringwald 	printf("sdp_query_rfcomm_channel_and_name_for_search_pattern\n");
18412381011SMilanka Ringwald }
18512381011SMilanka Ringwald 
18612381011SMilanka Ringwald 
18712381011SMilanka Ringwald void rfcomm_accept_connection_internal(uint16_t rfcomm_cid){
18812381011SMilanka Ringwald 	printf("rfcomm_accept_connection_internal \n");
18912381011SMilanka Ringwald }
19012381011SMilanka Ringwald 
191*dc5611fdSMilanka Ringwald // HFP Mock API
192*dc5611fdSMilanka Ringwald 
193*dc5611fdSMilanka Ringwald int expected_rfcomm_command(const char * cmd){
194*dc5611fdSMilanka Ringwald     char * ag_cmd = (char *)get_rfcomm_payload();
195*dc5611fdSMilanka Ringwald     int offset = 0;
196*dc5611fdSMilanka Ringwald     int cmd_size = strlen(cmd);
197*dc5611fdSMilanka Ringwald 
198*dc5611fdSMilanka Ringwald     if (memcmp(ag_cmd, "OK", 2) == 0){
199*dc5611fdSMilanka Ringwald         int ok_found = memcmp(ag_cmd+offset, "OK", 2) == 0;
200*dc5611fdSMilanka Ringwald         while (!ok_found && get_rfcomm_payload_len() - 2 >= offset){
201*dc5611fdSMilanka Ringwald             offset++;
202*dc5611fdSMilanka Ringwald             ok_found = memcmp(ag_cmd+offset, "OK", 2) == 0;
203*dc5611fdSMilanka Ringwald         }
204*dc5611fdSMilanka Ringwald         return ok_found;
205*dc5611fdSMilanka Ringwald     }
206*dc5611fdSMilanka Ringwald 
207*dc5611fdSMilanka Ringwald     int cmd_found = memcmp(ag_cmd, cmd, cmd_size) == 0;
208*dc5611fdSMilanka Ringwald     while (!cmd_found && get_rfcomm_payload_len() - cmd_size >= offset){
209*dc5611fdSMilanka Ringwald         offset++;
210*dc5611fdSMilanka Ringwald         cmd_found = strncmp(ag_cmd+offset, cmd, cmd_size) == 0;
211*dc5611fdSMilanka Ringwald     }
212*dc5611fdSMilanka Ringwald 
213*dc5611fdSMilanka Ringwald     if (!cmd_found) return 0;
214*dc5611fdSMilanka Ringwald     offset += strlen(cmd);
215*dc5611fdSMilanka Ringwald 
216*dc5611fdSMilanka Ringwald     int ok_found = memcmp(ag_cmd+offset, "OK", 2) == 0;
217*dc5611fdSMilanka Ringwald     while (!ok_found && get_rfcomm_payload_len() - 2 >= offset){
218*dc5611fdSMilanka Ringwald         offset++;
219*dc5611fdSMilanka Ringwald         ok_found = memcmp(ag_cmd+offset, "OK", 2) == 0;
220*dc5611fdSMilanka Ringwald     }
221*dc5611fdSMilanka Ringwald 
222*dc5611fdSMilanka Ringwald     return cmd_found && ok_found;
223*dc5611fdSMilanka Ringwald }
224*dc5611fdSMilanka Ringwald 
225*dc5611fdSMilanka Ringwald 
226*dc5611fdSMilanka Ringwald void inject_rfcomm_command(uint8_t * data, int len){
227*dc5611fdSMilanka Ringwald     prepare_rfcomm_buffer(data, len);
228*dc5611fdSMilanka Ringwald     (*registered_rfcomm_packet_handler)(active_connection, RFCOMM_DATA_PACKET, rfcomm_cid, (uint8_t *) &rfcomm_payload[0], rfcomm_payload_len);
229*dc5611fdSMilanka Ringwald }
230*dc5611fdSMilanka Ringwald 
231*dc5611fdSMilanka Ringwald 
232*dc5611fdSMilanka Ringwald 
233*dc5611fdSMilanka Ringwald 
234*dc5611fdSMilanka Ringwald 
235