1 /*
2 * Author: Yevgeniy Kiveisha <yevgeniy.kiveisha@intel.com>
3 * Copyright (c) 2014 Intel Corporation.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 #include <unistd.h>
26 #include <iostream>
27 #include "nrf8001.h"
28 #include "nrf8001-broadcast.h"
29 #include <lib_aci.h>
30 #include <aci_setup.h>
31 #include <signal.h>
32
33 #ifdef SERVICES_PIPE_TYPE_MAPPING_CONTENT
34 static services_pipe_type_mapping_t
35 services_pipe_type_mapping[NUMBER_OF_PIPES] = SERVICES_PIPE_TYPE_MAPPING_CONTENT;
36 #else
37 #define NUMBER_OF_PIPES 0
38 static services_pipe_type_mapping_t * services_pipe_type_mapping = NULL;
39 #endif
40
41 /**
42 * Store the setup for the nRF8001 in the flash of the AVR to save on RAM
43 */
44 static hal_aci_data_t setup_msgs[NB_SETUP_MESSAGES] = SETUP_MESSAGES_CONTENT;
45
46 /**
47 * aci_struct that will contain
48 * total initial credits
49 * current credit
50 * current state of the aci (setup/standby/active/sleep)
51 * open remote pipe pending
52 * close remote pipe pending
53 * Current pipe available bitmap
54 * Current pipe closed bitmap
55 * Current connection interval, slave latency and link supervision timeout
56 * Current State of the the GATT client (Service Discovery)
57 * Status of the bond (R) Peer address
58 */
59 static struct aci_state_t aci_state;
60
61 /**
62 * Temporary buffers for sending ACI commands
63 */
64 static hal_aci_evt_t aci_data;
65
66 void
sig_handler(int signo)67 sig_handler(int signo)
68 {
69 printf("got signal\n");
70 if (signo == SIGINT) {
71 printf("exiting application\n");
72 }
73 }
74
75 void
init_aci_setup()76 init_aci_setup () {
77 /**
78 * Point ACI data structures to the the setup data that the nRFgo studio generated for the nRF8001
79 */
80 if (NULL != services_pipe_type_mapping) {
81 aci_state.aci_setup_info.services_pipe_type_mapping = &services_pipe_type_mapping[0];
82 } else {
83 aci_state.aci_setup_info.services_pipe_type_mapping = NULL;
84 }
85
86 aci_state.aci_setup_info.number_of_pipes = NUMBER_OF_PIPES;
87 aci_state.aci_setup_info.setup_msgs = setup_msgs;
88 aci_state.aci_setup_info.num_setup_msgs = NB_SETUP_MESSAGES;
89 }
90
91 int
main(int argc,char ** argv)92 main(int argc, char **argv)
93 {
94 //! [Interesting]
95
96 init_aci_setup ();
97 init_local_interfaces (&aci_state, 10, 8, 4);
98
99 while (1) {
100 static bool setup_required = false;
101 if (lib_aci_event_get (&aci_state, &aci_data)) {
102 aci_evt_t * aci_evt;
103 aci_evt = &aci_data.evt;
104
105 switch(aci_evt->evt_opcode) {
106 /**
107 As soon as you reset the nRF8001 you will get an ACI Device Started Event
108 */
109 case ACI_EVT_DEVICE_STARTED: {
110 aci_state.data_credit_available = aci_evt->params.device_started.credit_available;
111 switch(aci_evt->params.device_started.device_mode) {
112 case ACI_DEVICE_SETUP:
113 /**
114 When the device is in the setup mode
115 */
116 printf ("Evt Device Started: Setup\n");
117 setup_required = true;
118 break;
119
120 case ACI_DEVICE_STANDBY:
121 printf ("Evt Device Started: Standby\n");
122 lib_aci_broadcast(10/* in seconds */, 0x0100 /* advertising interval 100ms */);
123 printf ("Broadcasting started\n");
124 break;
125 }
126 }
127 break; //ACI Device Started Event
128
129 case ACI_EVT_CMD_RSP:
130 if (ACI_STATUS_SUCCESS != aci_evt->params.cmd_rsp.cmd_status) {
131 printf ("ACI_EVT_CMD_RSP\n");
132 while (1);
133 }
134 break;
135
136 case ACI_EVT_CONNECTED:
137 printf ("ACI_EVT_CONNECTED\n");
138 break;
139
140 case ACI_EVT_PIPE_STATUS:
141 printf ("ACI_EVT_PIPE_STATUS\n");
142 break;
143
144 case ACI_EVT_DISCONNECTED:
145 if (ACI_STATUS_ERROR_ADVT_TIMEOUT == aci_evt->params.disconnected.aci_status) {
146 printf ("Broadcasting timed out\n");
147 } else {
148 printf ("Evt Disconnected. Link Loss\n");
149 }
150 break;
151
152 case ACI_EVT_DATA_RECEIVED:
153 printf ("ACI_EVT_DATA_RECEIVED\n");
154 break;
155
156 case ACI_EVT_HW_ERROR:
157 printf ("ACI_EVT_HW_ERROR\n");
158 break;
159 }
160 }
161
162 if (setup_required) {
163 if (SETUP_SUCCESS == do_aci_setup(&aci_state)) {
164 setup_required = false;
165 }
166 }
167 usleep (100);
168 }
169
170 close_local_interfaces (&aci_state);
171
172 //! [Interesting]
173
174 std::cout << "exiting application" << std::endl;
175
176 return 0;
177 }
178