MAXREFDES73# Code Documentation  V02.00
WEARABLE, GALVANIC SKIN RESPONSE SYSTEM
 All Data Structures Files Functions Variables Enumerator Macros Pages
fit_main.c
Go to the documentation of this file.
1 
47 #include "mxc_config.h"
48 
49 #include <string.h>
50 #include "wsf_types.h"
51 #include "bstream.h"
52 #include "wsf_msg.h"
53 #include "wsf_trace.h"
54 #include "hci_api.h"
55 #include "dm_api.h"
56 #include "att_api.h"
57 #include "app_api.h"
58 #include "app_db.h"
59 #include "app_ui.h"
60 #include "app_hw.h"
61 #include "svc_ch.h"
62 #include "svc_core.h"
63 #include "svc_hrs.h"
64 #include "svc_dis.h"
65 #include "svc_batt.h"
66 #include "bas_api.h"
67 #include "hrps_api.h"
68 #include "gpio.h"
69 #include "rtc.h"
70 
71 /*************************************************************************************************
72  Macros
73 **************************************************************************************************/
74 extern uint8_t BLEadvertising, BLEconnected;
75 
76 
77 /* LED pin mapping on the MAXREFDES73 */
78 #define LED_ON 0
79 #define LED_OFF 1
80 
81 #define LED_PORT 0
82 #define RED_LED_PIN 7
83 #define GREEN_LED_PIN 6
84 
86 #define FIT_MSG_START 0xA0
87 
89 enum {
92 };
93 
94 /**************************************************************************************************
95  Data Types
96 **************************************************************************************************/
97 
99 typedef union
100 {
101  wsfMsgHdr_t hdr;
102  dmEvt_t dm;
103  attsCccEvt_t ccc;
104 } fitMsg_t;
105 
106 /**************************************************************************************************
107  Configurable Parameters
108 **************************************************************************************************/
109 
111 static const appSlaveCfg_t fitSlaveCfg = {
112  {
113  { 5000, 5000, 0},
114  { 5000, 5000, 0}
115  },
116  {
117  { 800, 800, 800},
118  { 800, 800, 800}
119  },
120  TRUE
121 };
122 
124 static const appSecCfg_t fitSecCfg = {
125  DM_AUTH_BOND_FLAG,
126  0,
127  DM_KEY_DIST_LTK,
128  FALSE,
129  FALSE
130 };
131 
133 static const appUpdateCfg_t fitUpdateCfg = {
134  0,
136  640,
137  800,
138  0,
139  600,
140  5
141 };
142 
144 static const hrpsCfg_t fitHrpsCfg = {
145  1000
146 };
147 
149 static const basCfg_t fitBasCfg = {
150  1,
151  1,
152  300
153 };
154 
155 /**************************************************************************************************
156  Advertising Data
157 **************************************************************************************************/
158 
160 static const uint8_t fitAdvDataDisc[] =
161  {
163  2,
164  DM_ADV_TYPE_FLAGS,
165  DM_FLAG_LE_GENERAL_DISC |
166  DM_FLAG_LE_BREDR_NOT_SUP,
167 
169  2,
170  DM_ADV_TYPE_TX_POWER,
171  0,
174  7,
175  DM_ADV_TYPE_16_UUID,
176  UINT16_TO_BYTES(ATT_UUID_HEART_RATE_SERVICE),
177  UINT16_TO_BYTES(ATT_UUID_DEVICE_INFO_SERVICE),
178  UINT16_TO_BYTES(ATT_UUID_BATTERY_SERVICE)
179  };
180 
182 static const uint8_t fitScanDataDisc[] =
183  {
185  13,
186  DM_ADV_TYPE_LOCAL_NAME,
187  'M',
188  'A',
189  'X',
190  'R',
191  'E',
192  'F',
193  'D',
194  'E',
195  'S',
196  '7',
197  '3',
198  '#'
199  };
200 
201 /**************************************************************************************************
202  Client Characteristic Configuration Descriptors
203 **************************************************************************************************/
204 
206 enum
207  {
212  };
213 
215 static const attsCccSet_t fitCccSet[FIT_NUM_CCC_IDX] =
216  {
217  /* cccd handle value range security level */
218  {GATT_SC_CH_CCC_HDL, ATT_CLIENT_CFG_INDICATE, DM_SEC_LEVEL_NONE}, /* FIT_GATT_SC_CCC_IDX */
219  {HRS_HRM_CH_CCC_HDL, ATT_CLIENT_CFG_NOTIFY, DM_SEC_LEVEL_NONE}, /* FIT_HRS_HRM_CCC_IDX */
220  {BATT_LVL_CH_CCC_HDL, ATT_CLIENT_CFG_NOTIFY, DM_SEC_LEVEL_NONE} /* FIT_BATT_LVL_CCC_IDX */
221  };
222 
223 /**************************************************************************************************
224  Global Variables
225 **************************************************************************************************/
226 
228 wsfHandlerId_t fitHandlerId;
229 
230 /*************************************************************************************************/
240 /*************************************************************************************************/
241 static void fitDmCback(dmEvt_t *pDmEvt)
242 {
243  dmEvt_t *pMsg;
244 
245  if ((pMsg = WsfMsgAlloc(sizeof(dmEvt_t))) != NULL)
246  {
247  memcpy(pMsg, pDmEvt, sizeof(dmEvt_t));
248  WsfMsgSend(fitHandlerId, pMsg);
249  }
250 }
251 
252 /*************************************************************************************************/
262 /*************************************************************************************************/
263 static void fitAttCback(attEvt_t *pEvt)
264 {
265 
266  return;
267 }
268 
269 /*************************************************************************************************/
279 /*************************************************************************************************/
280 static void fitCccCback(attsCccEvt_t *pEvt)
281 {
282  attsCccEvt_t *pMsg;
283  appDbHdl_t dbHdl;
284 
285  /* if CCC not set from initialization and there's a device record */
286  if ((pEvt->handle != ATT_HANDLE_NONE) &&
287  ((dbHdl = AppDbGetHdl((dmConnId_t) pEvt->hdr.param)) != APP_DB_HDL_NONE))
288  {
289  /* store value in device database */
290  AppDbSetCccTblValue(dbHdl, pEvt->idx, pEvt->value);
291  }
292 
293  if ((pMsg = WsfMsgAlloc(sizeof(attsCccEvt_t))) != NULL)
294  {
295  memcpy(pMsg, pEvt, sizeof(attsCccEvt_t));
296  WsfMsgSend(fitHandlerId, pMsg);
297  }
298 }
299 
300 /*************************************************************************************************/
310 /*************************************************************************************************/
311 static void fitProcCccState(fitMsg_t *pMsg)
312 {
313  APP_TRACE_INFO3("ccc state ind value:%d handle:%d idx:%d", pMsg->ccc.value,
314  pMsg->ccc.handle, pMsg->ccc.idx);
315 
316  /* handle heart rate measurement CCC */
317  if (pMsg->ccc.idx == FIT_HRS_HRM_CCC_IDX)
318  {
319  if (pMsg->ccc.value == ATT_CLIENT_CFG_NOTIFY)
320  {
321  HrpsMeasStart((dmConnId_t) pMsg->ccc.hdr.param, FIT_HR_TIMER_IND, FIT_HRS_HRM_CCC_IDX);
322  }
323  else
324  {
325  HrpsMeasStop();
326  }
327  return;
328  }
329 
330  /* handle battery level CCC */
331  if (pMsg->ccc.idx == FIT_BATT_LVL_CCC_IDX)
332  {
333  if (pMsg->ccc.value == ATT_CLIENT_CFG_NOTIFY)
334  {
335  BasMeasBattStart((dmConnId_t) pMsg->ccc.hdr.param, FIT_BATT_TIMER_IND, FIT_BATT_LVL_CCC_IDX);
336  }
337  else
338  {
339  BasMeasBattStop();
340  }
341  return;
342  }
343 }
344 
345 /*************************************************************************************************/
355 /*************************************************************************************************/
356 static void fitClose(fitMsg_t *pMsg)
357 {
358  /* stop heart rate measurement */
359  HrpsMeasStop();
360 
361  /* stop battery measurement */
362  BasMeasBattStop();
363 }
364 
365 /*************************************************************************************************/
376 /*************************************************************************************************/
377 static void fitSetup(fitMsg_t *pMsg)
378 {
379  bdAddr_t randAddr;
380  uint32_t random_num = RTC_GetVal();
381 
382  /* set random address to a unique value */
383  randAddr[0] = random_num & 0xff;
384  randAddr[1] = (random_num >> 8) & 0xff;
385  randAddr[2] = (random_num >> 16) & 0xff;
386  randAddr[3] = (random_num >> 24) & 0xff;
387 
388  random_num /= 2;
389  randAddr[4] = random_num & 0xff;
390  randAddr[5] = (random_num >> 8) & 0xff;
391 
392  /* set as static address; this may alter the value of addr[5] */
393  DM_RAND_ADDR_SET(randAddr, DM_RAND_ADDR_STATIC);
394 
395  /* use random address */
396  DmDevSetRandAddr(randAddr);
397  DmAdvSetAddrType(DM_ADDR_RANDOM);
398 
399  /* set advertising and scan response data for discoverable mode */
400  AppAdvSetData(APP_ADV_DATA_DISCOVERABLE, sizeof(fitAdvDataDisc), (uint8_t *) fitAdvDataDisc);
401  AppAdvSetData(APP_SCAN_DATA_DISCOVERABLE, sizeof(fitScanDataDisc), (uint8_t *) fitScanDataDisc);
402 
403  /* set advertising and scan response data for connectable mode */
404  AppAdvSetData(APP_ADV_DATA_CONNECTABLE, 0, NULL);
405  AppAdvSetData(APP_SCAN_DATA_CONNECTABLE, 0, NULL);
406 
407  /* start advertising; automatically set connectable/discoverable mode and bondable mode */
408  AppAdvStart(APP_MODE_AUTO_INIT);
409 }
410 
411 /*************************************************************************************************/
421 /*************************************************************************************************/
422 static void fitBtnCback(uint8_t btn)
423 {
424  dmConnId_t connId;
425  static uint8_t heartRate = 78; /* for testing/demonstration */
426 
427  /* button actions when connected */
428  if ((connId = AppConnIsOpen()) != DM_CONN_ID_NONE)
429  {
430  switch (btn)
431  {
432  case APP_UI_BTN_1_SHORT:
433  /* increment the heart rate */
434  AppHwHrmTest(++heartRate);
435  break;
436 
437  case APP_UI_BTN_1_MED:
438  break;
439 
440  case APP_UI_BTN_1_LONG:
441  AppConnClose(connId);
442  break;
443 
444  case APP_UI_BTN_2_SHORT:
445  /* decrement the heart rate */
446  AppHwHrmTest(--heartRate);
447  break;
448 
449  default:
450  break;
451  }
452  }
453  /* button actions when not connected */
454  else
455  {
456  switch (btn)
457  {
458  case APP_UI_BTN_1_SHORT:
459  /* start or restart advertising */
460  AppAdvStart(APP_MODE_AUTO_INIT);
461  break;
462 
463  case APP_UI_BTN_1_MED:
464  /* enter discoverable and bondable mode mode */
465  AppSetBondable(TRUE);
466  AppAdvStart(APP_MODE_DISCOVERABLE);
467  break;
468 
469  case APP_UI_BTN_1_LONG:
470  /* clear bonded device info and restart advertising */
471  AppDbDeleteAllRecords();
472  AppAdvStart(APP_MODE_AUTO_INIT);
473  break;
474 
475  default:
476  break;
477  }
478  }
479 }
480 
481 /*************************************************************************************************/
491 /*************************************************************************************************/
492 static void fitProcMsg(fitMsg_t *pMsg)
493 {
494  uint8_t uiEvent = APP_UI_NONE;
495 
496  switch(pMsg->hdr.event)
497  {
498  case FIT_HR_TIMER_IND:
499  HrpsProcMsg(&pMsg->hdr);
500  break;
501 
502  case FIT_BATT_TIMER_IND:
503  BasProcMsg(&pMsg->hdr);
504  break;
505 
506  case ATTS_CCC_STATE_IND:
507  fitProcCccState(pMsg);
508  break;
509 
510  case DM_RESET_CMPL_IND:
511  fitSetup(pMsg);
512  uiEvent = APP_UI_RESET_CMPL;
513  break;
514 
515  case DM_ADV_START_IND:
516  uiEvent = APP_UI_ADV_START;
517  GPIO_SetOutVal(LED_PORT, GREEN_LED_PIN, LED_ON);
518  BLEadvertising = 1;
519  break;
520 
521  case DM_ADV_STOP_IND:
522  uiEvent = APP_UI_ADV_STOP;
523  GPIO_SetOutVal(LED_PORT, GREEN_LED_PIN, LED_OFF);
524  BLEadvertising = 0;
525  break;
526 
527  case DM_CONN_OPEN_IND:
528  uiEvent = APP_UI_CONN_OPEN;
529  GPIO_SetOutVal(LED_PORT, RED_LED_PIN, LED_ON);
530  BLEconnected = 1;
531  //MG added
532  GPIO_SetOutVal(LED_PORT, GREEN_LED_PIN, LED_OFF);
533  break;
534 
535  case DM_CONN_CLOSE_IND:
536  fitClose(pMsg);
537  uiEvent = APP_UI_CONN_CLOSE;
538  GPIO_SetOutVal(LED_PORT, RED_LED_PIN, LED_OFF);
539  BLEconnected = 0;
540  break;
541 
542  case DM_SEC_PAIR_CMPL_IND:
543  uiEvent = APP_UI_SEC_PAIR_CMPL;
544  break;
545 
546  case DM_SEC_PAIR_FAIL_IND:
547  uiEvent = APP_UI_SEC_PAIR_FAIL;
548  break;
549 
550  case DM_SEC_ENCRYPT_IND:
551  uiEvent = APP_UI_SEC_ENCRYPT;
552  break;
553 
554  case DM_SEC_ENCRYPT_FAIL_IND:
555  uiEvent = APP_UI_SEC_ENCRYPT_FAIL;
556  break;
557 
558  case DM_SEC_AUTH_REQ_IND:
559  AppHandlePasskey(&pMsg->dm.authReq);
560  break;
561 
562  default:
563  break;
564  }
565 
566  if (uiEvent != APP_UI_NONE)
567  {
568  AppUiAction(uiEvent);
569  }
570 }
571 
572 /*************************************************************************************************/
582 /*************************************************************************************************/
583 void FitHandlerInit(wsfHandlerId_t handlerId)
584 {
585  APP_TRACE_INFO0("FitHandlerInit");
586 
587  /* store handler ID */
588  fitHandlerId = handlerId;
589 
590  /* Set configuration pointers */
591  pAppSlaveCfg = (appSlaveCfg_t *) &fitSlaveCfg;
592  pAppSecCfg = (appSecCfg_t *) &fitSecCfg;
593  pAppUpdateCfg = (appUpdateCfg_t *) &fitUpdateCfg;
594 
595  /* Initialize application framework */
596  AppSlaveInit();
597 
598  /* initialize battery service server */
599  BasInit(handlerId, (basCfg_t *) &fitBasCfg);
600 
601  /* initialize heart rate profile sensor */
602  HrpsInit(handlerId, (hrpsCfg_t *) &fitHrpsCfg);
603  HrpsSetFlags(CH_HRM_FLAGS_VALUE_8BIT | CH_HRM_FLAGS_ENERGY_EXP);
604 }
605 
606 /*************************************************************************************************/
617 /*************************************************************************************************/
618 void FitHandler(wsfEventMask_t event, wsfMsgHdr_t *pMsg)
619 {
620  if (pMsg != NULL)
621  {
622  APP_TRACE_INFO1("Fit got evt %d", pMsg->event);
623 
624  if (pMsg->event >= DM_CBACK_START && pMsg->event <= DM_CBACK_END)
625  {
626  /* process advertising and connection-related messages */
627  AppSlaveProcDmMsg((dmEvt_t *) pMsg);
628 
629  /* process security-related messages */
630  AppSlaveSecProcDmMsg((dmEvt_t *) pMsg);
631  }
632 
633  /* perform profile and user interface-related operations */
634  fitProcMsg((fitMsg_t *) pMsg);
635  }
636 }
637 
638 /*************************************************************************************************/
646 /*************************************************************************************************/
647 void FitStart(void)
648 {
649  /* Register for stack callbacks */
650  DmRegister(fitDmCback);
651  DmConnRegister(DM_CLIENT_ID_APP, fitDmCback);
652  AttRegister(fitAttCback);
653  AttConnRegister(AppServerConnCback);
654  AttsCccRegister(FIT_NUM_CCC_IDX, (attsCccSet_t *) fitCccSet, fitCccCback);
655 
656  /* Register for app framework callbacks */
657  AppUiBtnRegister(fitBtnCback);
658 
659  /* Initialize attribute server database */
660  SvcCoreAddGroup();
661  SvcHrsCbackRegister(NULL, HrpsWriteCback);
662  SvcHrsAddGroup();
663  SvcDisAddGroup();
664  SvcBattCbackRegister(BasReadCback, NULL);
665  SvcBattAddGroup();
666 
667  /* Reset the device */
668  DmDevReset();
669 }