nrf8001: added new BLE module with broadcasting example
[contrib/upm.git] / examples / nrf8001_broadcast.cxx
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
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
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
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 }