phd_com_model.c 40 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111
  1. /******************************************************************************
  2. *
  3. * Freescale Semiconductor Inc.
  4. * (c) Copyright 2004-2010 Freescale Semiconductor, Inc.
  5. * ALL RIGHTS RESERVED.
  6. *
  7. ******************************************************************************
  8. *
  9. * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
  10. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  11. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  12. * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
  13. * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  14. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  15. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  16. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  17. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
  18. * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  19. * THE POSSIBILITY OF SUCH DAMAGE.
  20. *
  21. **************************************************************************//*!
  22. *
  23. * @file phdc_com_model.c
  24. *
  25. * @author
  26. *
  27. * @version
  28. *
  29. * @date May-28-2009
  30. * @brief This file packetizes the data to be sent according to the IEEE_11073
  31. * protocol.
  32. *****************************************************************************/
  33. /******************************************************************************
  34. * Includes
  35. *****************************************************************************/
  36. #include "hidef.h" /* for EnableInterrupts macro */
  37. #include "derivative.h" /* include peripheral declarations */
  38. #include "types.h" /* User Defined Data Types */
  39. #include "phd_com_model.h" /* IEEE11073 Header File */
  40. #include "phdc_app.h" /* PHDC Application Header File */
  41. #include "usb_phdc.h" /* USB PHDC Class Header File */
  42. #include "usb_descriptor.h" /* PHDC App Descriptor Header File */
  43. #if (defined LITTLE_ENDIAN)
  44. #include "ieee11073_phd_types_kinetis.h" /* IEEE11073 Data Structures */
  45. #else
  46. #include "ieee11073_phd_types.h" /* IEEE11073 Data Structures */
  47. #endif
  48. #include "ieee11073_nom_codes.h" /* IEEE11073 Nomenclature Codes */
  49. #include "RealTimerCounter.h"
  50. /* skip the inclusion in dependency stage */
  51. #ifndef __NO_SETJMP
  52. #include <stdio.h>
  53. #endif
  54. #include <string.h>
  55. #if (defined _MCF51MM256_H) || (defined _MCF51JE256_H)
  56. #include "exceptions.h"
  57. #endif
  58. /*****************************************************************************
  59. * Global Functions Prototypes
  60. *****************************************************************************/
  61. /****************************************************************************
  62. * Global Variables - None
  63. ****************************************************************************/
  64. /*****************************************************************************
  65. * Local Types - None
  66. *****************************************************************************/
  67. /*****************************************************************************
  68. * Local Functions Prototypes
  69. *****************************************************************************/
  70. static void PHD_Assoc_Response_Handler(uint_8 controller_ID, APDU* val);
  71. static void PHD_Unhandled_Request(uint_8 controller_ID, APDU* val);
  72. static void PHD_Disconnect_Handler(uint_8 controller_ID, APDU* val);
  73. static void PHD_Connect_Handler(uint_8 controller_ID, APDU* val);
  74. static void PHD_Config_Event_Report_Handler(uint_8 controller_ID, APDU* val);
  75. static void PHD_ABRT_Request_Handler(uint_8 controller_ID, APDU* val);
  76. static void PHD_Assoc_RelRes_Handler(uint_8 controller_ID, APDU* val);
  77. static void PHD_Assoc_RelReq_Handler(uint_8 controller_ID, APDU* val);
  78. static void PHD_OPN_STATE_PRST_APDU_Handler(uint_8 controller_ID, APDU* val);
  79. static uint_8 PHD_Remove_Timer(uint_8_ptr pindex);
  80. static uint_8 PHD_Add_Timer(PTIMER_OBJECT pTimerObject);
  81. void PHD_Callback(uint_8 controller_ID, uint_8 event_type, void* val);
  82. #ifndef TIMER_CALLBACK_ARG
  83. static void PHD_Association_Timer_Callback(void);
  84. static void PHD_Configuration_Timer_Callback(void);
  85. static void PHD_Msr_Timer_Callback(void);
  86. static void PHD_Disassociation_Timer_Callback(void);
  87. #else
  88. static void PHD_Association_Timer_Callback(void* arg);
  89. static void PHD_Configuration_Timer_Callback(void* arg);
  90. static void PHD_Msr_Timer_Callback(void* arg);
  91. static void PHD_Disassociation_Timer_Callback(void* arg);
  92. #endif
  93. /*****************************************************************************
  94. * Constant and Macro's
  95. *****************************************************************************/
  96. PHD_STATE_MC_FUNC const phd_state_mc_func[AG_MAX_STATES][AG_MAX_EVENTS] =
  97. {
  98. /* PHD_AG_STATE_DISCONNECTED */
  99. PHD_Disconnect_Handler,PHD_Connect_Handler, NULL, NULL, NULL, NULL, NULL,NULL,
  100. /* PHD_AG_STATE_CON_UNASSOCIATED */
  101. PHD_Disconnect_Handler,PHD_Connect_Handler,PHD_Unhandled_Request, NULL, NULL, NULL,PHD_ABRT_Request_Handler,NULL,
  102. /* PHD_AG_STATE_CON_ASSOCIATING */
  103. PHD_Disconnect_Handler,PHD_Connect_Handler,PHD_Unhandled_Request,PHD_Assoc_Response_Handler, NULL, NULL,PHD_ABRT_Request_Handler,PHD_OPN_STATE_PRST_APDU_Handler,
  104. /* PHD_AG_STATE_CON_ASSOC_CFG_SENDING_CONFIG */
  105. PHD_Disconnect_Handler,PHD_Connect_Handler,PHD_Unhandled_Request, NULL,PHD_Assoc_RelReq_Handler, NULL,PHD_ABRT_Request_Handler,PHD_OPN_STATE_PRST_APDU_Handler,
  106. /* PHD_AG_STATE_CON_ASSOC_CFG_WAITING_APPROVAL */
  107. PHD_Disconnect_Handler,PHD_Connect_Handler,PHD_Unhandled_Request, NULL,PHD_Assoc_RelReq_Handler, NULL,PHD_ABRT_Request_Handler,PHD_OPN_STATE_PRST_APDU_Handler,
  108. /* PHD_AG_STATE_CON_ASSOC_OPERATING */
  109. PHD_Disconnect_Handler,PHD_Connect_Handler,PHD_Unhandled_Request, NULL,PHD_Assoc_RelReq_Handler, NULL,PHD_ABRT_Request_Handler,PHD_OPN_STATE_PRST_APDU_Handler,
  110. /* PHD_AG_STATE_CON_DISASSOCIATING */
  111. PHD_Disconnect_Handler,PHD_Connect_Handler,PHD_Unhandled_Request, NULL,PHD_Assoc_RelReq_Handler,PHD_Assoc_RelRes_Handler,PHD_ABRT_Request_Handler,NULL
  112. };
  113. /*****************************************************************************
  114. * Local Variables
  115. *****************************************************************************/
  116. static PHD_CALLBACK g_phd_callback;
  117. #ifdef _MC9S08JS16_H
  118. #pragma DATA_SEG PHD_BUFFER
  119. #endif
  120. static uint_8 phd_buffer[PHD_BUFF_SIZE]; /* buffer used for get
  121. attributes response
  122. and measurements */
  123. #ifdef _MC9S08JS16_H
  124. #pragma DATA_SEG DEFAULT
  125. #endif
  126. static uint_16 phd_buffer_offset;
  127. /* variables to keep track of the phd_buffer usage */
  128. static boolean g_phd_buffer_being_used = FALSE;
  129. static boolean g_sent_resp_get_attr = FALSE;
  130. /* initialize the device state */
  131. static uint_8 phd_com_state = PHD_AG_STATE_DISCONNECTED;
  132. static uint_8 timer_index = INVALID_TIMER_VALUE;
  133. static uint_8 assoc_retry_count = PHD_ASSOC_RETRY_COUNT;
  134. static uint_8 g_controllerID;
  135. /*****************************************************************************
  136. * Local Functions
  137. *****************************************************************************/
  138. #if (defined LITTLE_ENDIAN)
  139. intu16 SWAPBYTE16(intu16 a)
  140. {
  141. return ((a >> (intu16)0x08) | ((a & 0xFF) << (intu16)0x08));
  142. }
  143. intu32 SWAPBYTE32(intu32 a)
  144. {
  145. return (intu32)((SWAPBYTE16((uint_32)(a) & (uint_32)0xFFFF) << 0x10) |(SWAPBYTE16((uint_32)((a) >> 0x10))));
  146. }
  147. #else
  148. #define SWAPBYTE16(a) (a)
  149. #define SWAPBYTE32(a) (a)
  150. #endif
  151. /******************************************************************************
  152. *
  153. * @name PHD_OPN_STATE_PRST_APDU_Handler
  154. *
  155. * @brief This function handles the request/data sent by the host when
  156. * the device is in operating state
  157. *
  158. * @param controller_ID : Controller ID
  159. * @param val : Pointer to APDU received
  160. *
  161. * @return None
  162. *
  163. *****************************************************************************
  164. * This function parses the data received and checks whether it is a response
  165. * to the attributes sent or the response to the measurement data
  166. *****************************************************************************/
  167. static void PHD_OPN_STATE_PRST_APDU_Handler (
  168. uint_8 controller_ID, /* [IN] Controller ID */
  169. APDU* val /* [IN] Pointer to APDU received */
  170. )
  171. {
  172. extern uint_8 const PHD_WSL_DIM_GET_RSP[];
  173. if( (val->choice == PRST_CHOSEN) &&
  174. (
  175. (phd_com_state == PHD_AG_STATE_CON_ASSOC_OPERATING) ||
  176. (phd_com_state == PHD_AG_STATE_CON_ASSOCIATING) ||
  177. (phd_com_state == PHD_AG_STATE_CON_ASSOC_CFG_SENDING_CONFIG) ||
  178. (phd_com_state == PHD_AG_STATE_CON_ASSOC_CFG_WAITING_APPROVAL)
  179. )
  180. )
  181. {
  182. /* get the APDU received starting from invoke id */
  183. DATA_apdu *p_data_pdu = (DATA_apdu *)&(val->u.prst.value);
  184. if(p_data_pdu->choice.choice == ROIV_CMIP_GET_CHOSEN)
  185. {/* its the Get command */
  186. if(p_data_pdu->choice.u.roiv_cmipGet.attribute_id_list.count == 0)
  187. {
  188. /* count 0 implies the whole MDS class */
  189. uint_16 invoke_id = SWAPBYTE16(p_data_pdu->invoke_id);
  190. /* if phd_buffer is already in use, return */
  191. /* Safe to test without Disable/Enable interrupts, PHD_OPN_STATE_PRST_APDU_Handler
  192. is only called from interrupt context
  193. */
  194. if(g_phd_buffer_being_used == TRUE)
  195. {
  196. return;
  197. }
  198. g_phd_buffer_being_used = TRUE;
  199. /* copy the get attribute response into the phd_buffer */
  200. (void)memcpy(phd_buffer, PHD_WSL_DIM_GET_RSP, DIM_GET_RSP_SIZE);
  201. /* get the invoke id from the get attribute request sent
  202. by manager */
  203. #if (defined LITTLE_ENDIAN)
  204. phd_buffer[6] = (uint_8)((invoke_id >> 8)
  205. & LOW_BYTE_MASK);
  206. phd_buffer[7]= (uint_8)((invoke_id) & LOW_BYTE_MASK);
  207. #else
  208. phd_buffer[6] = (uint_8)((invoke_id >> UPPER_BYTE_SHIFT)
  209. & LOW_BYTE_MASK);
  210. phd_buffer[7]= (uint_8)((invoke_id) & LOW_BYTE_MASK);
  211. #endif
  212. g_sent_resp_get_attr=TRUE;
  213. /* Send Atributes to Manager */
  214. (void)USB_Class_PHDC_Send_Data(controller_ID, FALSE, 0,
  215. SEND_DATA_QOS, (uint_8_ptr)phd_buffer,
  216. (USB_PACKET_SIZE)DIM_GET_RSP_SIZE);
  217. }
  218. }
  219. else if(p_data_pdu->choice.choice == RORS_CMIP_CONFIRMED_EVENT_REPORT_CHOSEN)
  220. {
  221. if(phd_com_state == PHD_AG_STATE_CON_ASSOC_CFG_WAITING_APPROVAL)
  222. {
  223. /* confirmed */
  224. /* configuration accepted */
  225. ConfigReportRsp *p_rsp = (ConfigReportRsp *)p_data_pdu->choice.
  226. u.rors_cmipConfirmedEventReport.event_reply_info.value;
  227. if((p_rsp->config_report_id == EXTENDED_CONFIG_START) &&
  228. (p_rsp->config_result == ACCEPTED_CONFIG ))
  229. {
  230. (void)PHD_Remove_Timer(&timer_index);
  231. /* if configuration accepted, enter operating state */
  232. phd_com_state = PHD_AG_STATE_CON_ASSOC_OPERATING;
  233. g_phd_callback(controller_ID,APP_PHD_CONNECTED_TO_HOST);
  234. g_sent_resp_get_attr=FALSE;
  235. }
  236. else
  237. {
  238. /* configuration not accepted by the manager */
  239. phd_com_state = PHD_AG_STATE_CON_ASSOC_CFG_SENDING_CONFIG;
  240. }
  241. }
  242. else
  243. {
  244. /* confirmed report on completion */
  245. /* if the received APDU is the response to the measurements sent */
  246. (void)PHD_Remove_Timer(&timer_index);
  247. g_phd_callback(controller_ID,APP_PHD_MEASUREMENT_SENT);
  248. }
  249. }
  250. }
  251. }
  252. /******************************************************************************
  253. *
  254. * @name PHD_Config_Event_Report_Handler
  255. *
  256. * @brief This function handles the response sent by the host after
  257. * config report is sent to the host for approval
  258. *
  259. * @param controller_ID : Controller ID
  260. * @param val : Pointer to APDU received
  261. *
  262. * @return None
  263. *
  264. *****************************************************************************
  265. * This fucntion parses the response to the configuration event report sent
  266. * to check whether the configuration was accepted or rejected
  267. *****************************************************************************/
  268. static void PHD_Config_Event_Report_Handler (
  269. uint_8 controller_ID, /* [IN] Controller ID */
  270. APDU* val /* [IN] Pointer to APDU received */
  271. )
  272. {
  273. UNUSED (controller_ID)
  274. if(( phd_com_state == PHD_AG_STATE_CON_ASSOC_CFG_WAITING_APPROVAL) &&
  275. ( val->choice == PRST_CHOSEN))
  276. {
  277. DATA_apdu *p_data_pdu = (DATA_apdu *)&(val->u.prst.value);
  278. (void)PHD_Remove_Timer(&timer_index);
  279. if(p_data_pdu->choice.choice ==
  280. RORS_CMIP_CONFIRMED_EVENT_REPORT_CHOSEN)
  281. {
  282. /* confirmed */
  283. /* configuration accepted */
  284. ConfigReportRsp *p_rsp = (ConfigReportRsp *)p_data_pdu->choice.
  285. u.rors_cmipConfirmedEventReport.event_reply_info.value;
  286. if((p_rsp->config_report_id == EXTENDED_CONFIG_START) &&
  287. (p_rsp->config_result == ACCEPTED_CONFIG ))
  288. {
  289. /* if configuration accepted, enter operating state */
  290. phd_com_state = PHD_AG_STATE_CON_ASSOC_OPERATING;
  291. }
  292. else
  293. {
  294. /* configuration not accepted by the manager */
  295. phd_com_state = PHD_AG_STATE_CON_ASSOC_CFG_SENDING_CONFIG;
  296. }
  297. }
  298. }
  299. }
  300. /******************************************************************************
  301. *
  302. * @name PHD_Assoc_Response_Handler
  303. *
  304. * @brief This function handles the assciation request response sent
  305. * by the host
  306. *
  307. * @param controller_ID : Controller ID
  308. * @param val : Pointer to APDU received
  309. *
  310. * @return None
  311. *
  312. *****************************************************************************
  313. * This function parses the association request response to check whether the
  314. * configuration was already known to the manager or not. In case the
  315. * configuartion was not known, configuration event report is sent
  316. *****************************************************************************/
  317. static void PHD_Assoc_Response_Handler (
  318. uint_8 controller_ID, /* [IN] Controller ID */
  319. APDU* val /* [IN] Pointer to APDU received */
  320. )
  321. {
  322. extern uint_8 const PHD_WSL_CNFG_EVT_RPT[];
  323. if(( phd_com_state == PHD_AG_STATE_CON_ASSOCIATING) &&
  324. ( val->choice == AARE_CHOSEN))
  325. {
  326. AARE_apdu *p_assoc_res = &(val->u.aare);
  327. (void)PHD_Remove_Timer(&timer_index);
  328. if( p_assoc_res->result == ACCEPTED_UNKNOWN_CONFIG)
  329. {
  330. /* if manager says the configuration is unknown, send configuration
  331. event report */
  332. phd_com_state = PHD_AG_STATE_CON_ASSOC_CFG_SENDING_CONFIG;
  333. /* send the configuration information */
  334. (void)USB_Class_PHDC_Send_Data(controller_ID, FALSE,0,SEND_DATA_QOS,
  335. (uint_8_ptr)PHD_WSL_CNFG_EVT_RPT,
  336. (USB_PACKET_SIZE)CNFG_EVT_RPT_SIZE);
  337. }
  338. else
  339. {
  340. /* if the configuration is already known to the manager, enter
  341. operating state */
  342. phd_com_state = PHD_AG_STATE_CON_ASSOC_OPERATING;
  343. g_phd_callback(controller_ID,APP_PHD_CONNECTED_TO_HOST);
  344. }
  345. }
  346. }
  347. /******************************************************************************
  348. *
  349. * @name PHD_Unhandled_Request
  350. *
  351. * @brief This function takes care of the unhandled request
  352. *
  353. * @param controller_ID : Controller ID
  354. * @param val : Pointer to APDU received
  355. *
  356. * @return None
  357. *
  358. *****************************************************************************
  359. * This function should take care of any request which is not supported or is
  360. * illegal
  361. *****************************************************************************/
  362. static void PHD_Unhandled_Request(
  363. uint_8 controller_ID, /* [IN] Controller ID */
  364. APDU* val /* [IN] Pointer to APDU received */
  365. )
  366. {
  367. UNUSED (controller_ID)
  368. UNUSED (val)
  369. }
  370. /******************************************************************************
  371. *
  372. * @name PHD_ABRT_Request_Handler
  373. *
  374. * @brief This function handles abrt req
  375. *
  376. * @param controller_ID : Controller ID
  377. * @param val : Pointer to APDU received
  378. *
  379. * @return None
  380. *
  381. *****************************************************************************
  382. * This handles the abort request sent by the manager
  383. *****************************************************************************/
  384. static void PHD_ABRT_Request_Handler(
  385. uint_8 controller_ID, /* [IN] Controller ID */
  386. APDU* val /* [IN] Pointer to APDU received */
  387. )
  388. {
  389. UNUSED (val)
  390. phd_com_state = PHD_AG_STATE_CON_UNASSOCIATED;
  391. assoc_retry_count = PHD_ASSOC_RETRY_COUNT;
  392. g_phd_callback(controller_ID, APP_PHD_DISCONNECTED_FROM_HOST);
  393. }
  394. /******************************************************************************
  395. *
  396. * @name PHD_Assoc_RelRes_Handler
  397. *
  398. * @brief This function handles association release response
  399. *
  400. * @param controller_ID : Controller ID
  401. * @param val : Pointer to APDU received
  402. *
  403. * @return None
  404. *
  405. *****************************************************************************
  406. * This function handles the association release response
  407. *****************************************************************************/
  408. static void PHD_Assoc_RelRes_Handler(
  409. uint_8 controller_ID, /* [IN] Controller ID */
  410. APDU* val /* [IN] Pointer to APDU received */
  411. )
  412. {
  413. UNUSED (val)
  414. (void)PHD_Remove_Timer(&timer_index);
  415. phd_com_state = PHD_AG_STATE_CON_UNASSOCIATED;
  416. assoc_retry_count = PHD_ASSOC_RETRY_COUNT;
  417. g_phd_callback(controller_ID, APP_PHD_DISCONNECTED_FROM_HOST);
  418. }
  419. /******************************************************************************
  420. *
  421. * @name PHD_Assoc_RelReq_Handler
  422. *
  423. * @brief This function handles association release request
  424. *
  425. * @param controller_ID : Controller ID
  426. * @param val : Pointer to APDU received
  427. *
  428. * @return None
  429. *
  430. *****************************************************************************
  431. * This function sends a response to the association release request
  432. *****************************************************************************/
  433. static void PHD_Assoc_RelReq_Handler(
  434. uint_8 controller_ID, /* [IN] Controller ID */
  435. APDU* val /* [IN] Pointer to APDU received */
  436. )
  437. {
  438. extern uint_8 const PHD_WSL_REL_RES[];
  439. UNUSED (val)
  440. (void)PHD_Remove_Timer(&timer_index);
  441. /* send release response */
  442. (void)USB_Class_PHDC_Send_Data(controller_ID, FALSE, 0, SEND_DATA_QOS,
  443. (uint_8_ptr)PHD_WSL_REL_RES, REL_RES_SIZE);
  444. phd_com_state = PHD_AG_STATE_CON_UNASSOCIATED;
  445. assoc_retry_count = PHD_ASSOC_RETRY_COUNT;
  446. g_phd_callback(controller_ID, APP_PHD_DISCONNECTED_FROM_HOST);
  447. }
  448. /******************************************************************************
  449. *
  450. * @name PHD_Disconnect_Handler
  451. *
  452. * @brief This function handles disconnect request
  453. *
  454. * @param controller_ID : Controller ID
  455. * @param val : Pointer to APDU received
  456. *
  457. * @return None
  458. *
  459. *****************************************************************************
  460. * Sets the PHDC state to disconnected
  461. *****************************************************************************/
  462. static void PHD_Disconnect_Handler(
  463. uint_8 controller_ID, /* [IN] Controller ID */
  464. APDU* val /* [IN] Pointer to APDU received */
  465. )
  466. {
  467. UNUSED (controller_ID)
  468. UNUSED (val)
  469. (void)PHD_Remove_Timer(&timer_index);
  470. phd_com_state = PHD_AG_STATE_DISCONNECTED;
  471. g_phd_callback(controller_ID, APP_PHD_UNINITIALISED);
  472. }
  473. /******************************************************************************
  474. *
  475. * @name PHD_Connect_Handler
  476. *
  477. * @brief This function handles connect request
  478. *
  479. * @param controller_ID : Controller ID
  480. * @param val : Pointer to APDU received
  481. *
  482. * @return None
  483. *
  484. *****************************************************************************
  485. * Sets the PHDC state to unassciated if it was disconnected
  486. *****************************************************************************/
  487. static void PHD_Connect_Handler(
  488. uint_8 controller_ID, /* [IN] Controller ID */
  489. APDU* val /* [IN] Pointer to APDU received */
  490. )
  491. {
  492. UNUSED (val)
  493. if(phd_com_state == PHD_AG_STATE_DISCONNECTED)
  494. {
  495. phd_com_state = PHD_AG_STATE_CON_UNASSOCIATED;
  496. assoc_retry_count = PHD_ASSOC_RETRY_COUNT;
  497. g_phd_callback(controller_ID, APP_PHD_INITIALISED);
  498. }
  499. }
  500. /******************************************************************************
  501. *
  502. * @name PHD_Callback
  503. *
  504. * @brief This function handles the callback
  505. *
  506. * @param controller_ID : Controller ID
  507. * @param event_tyoe : type of the event
  508. * @param val : Pointer to Received Buffer
  509. *
  510. * @return None
  511. *
  512. *****************************************************************************
  513. * This function is called from the class layer and handles the events (reset,
  514. * enumeration complete, send/recv complete)
  515. *****************************************************************************/
  516. void PHD_Callback(
  517. uint_8 controller_ID, /* [IN] Controller ID */
  518. uint_8 event_type, /* [IN] type of the event */
  519. void* val /* [IN] Pointer to Received Buffer */
  520. )
  521. {
  522. uint_8 trans_event = 0xff;
  523. switch (event_type)
  524. {
  525. case USB_APP_BUS_RESET:
  526. case USB_APP_CONFIG_CHANGED:
  527. /* on reset, transport is disconnected */
  528. trans_event = PHD_AG_EVT_TRANSPORT_DISCONNECTED;
  529. break;
  530. case USB_APP_ENUM_COMPLETE:
  531. /* when enumeration is complete, transport is connected */
  532. trans_event = PHD_AG_EVT_TRANSPORT_CONNECTED;
  533. break;
  534. case USB_APP_META_DATA_PARAMS_CHANGED:
  535. case USB_APP_ERROR:
  536. (void)USB_Class_PHDC_Recv_Data(controller_ID, PHDC_BULK_OUT_QOS, NULL, 0);
  537. return;
  538. break;
  539. case USB_APP_GET_DATA_BUFF:
  540. {
  541. /* called by lower layer to get recv buffer */
  542. PTR_USB_CLASS_PHDC_RX_BUFF rx_buff =
  543. (PTR_USB_CLASS_PHDC_RX_BUFF)val;
  544. /* Copy Received Data*/
  545. if(phd_buffer_offset == 0)
  546. {
  547. (void)memcpy(phd_buffer, rx_buff->in_buff, rx_buff->in_size);
  548. }
  549. #ifdef _MC9S08JS16_H
  550. phd_buffer_offset += rx_buff->in_size;
  551. (void)USB_Class_PHDC_Recv_Data(controller_ID, PHDC_BULK_OUT_QOS,
  552. phd_buffer + phd_buffer_offset,
  553. (uint_8)(rx_buff->transfer_size - phd_buffer_offset));
  554. #else
  555. phd_buffer_offset += rx_buff->in_size;
  556. (void)USB_Class_PHDC_Recv_Data(controller_ID, PHDC_BULK_OUT_QOS,
  557. phd_buffer + phd_buffer_offset,
  558. (uint_16)(rx_buff->transfer_size - phd_buffer_offset));
  559. #endif
  560. break;
  561. }
  562. case USB_APP_GET_TRANSFER_SIZE:
  563. {
  564. PTR_USB_CLASS_PHDC_XFER_SIZE xfer_size =
  565. (PTR_USB_CLASS_PHDC_XFER_SIZE)val;
  566. #if USB_METADATA_SUPPORTED
  567. if(xfer_size->meta_data_packet)
  568. {
  569. PTR_USB_META_DATA_MSG_PREAMBLE metadata_preamble_ptr =
  570. (PTR_USB_META_DATA_MSG_PREAMBLE)xfer_size->in_buff;
  571. xfer_size->transfer_size = (USB_PACKET_SIZE)
  572. (metadata_preamble_ptr->opaque_data_size +
  573. METADATA_HEADER_SIZE);
  574. }
  575. else
  576. #endif
  577. {
  578. APDU *papdu = (APDU*)xfer_size->in_buff;
  579. xfer_size->transfer_size = (USB_PACKET_SIZE)
  580. (papdu->length + APDU_HEADER_SIZE);
  581. }
  582. if(xfer_size->direction == USB_RECV)
  583. {
  584. phd_buffer_offset = 0;
  585. }
  586. break;
  587. }
  588. case USB_APP_DATA_RECEIVED:
  589. {
  590. PTR_USB_APP_EVENT_DATA_RECEIVED rx_buff =
  591. (PTR_USB_APP_EVENT_DATA_RECEIVED )val;
  592. /* Copy Received Data*/
  593. if(phd_buffer_offset == 0)
  594. {
  595. (void)memcpy(phd_buffer, rx_buff->buffer_ptr, rx_buff->size);
  596. }
  597. /* receive data complete */
  598. trans_event = PHD_AG_EVT_TRANSPORT_APDU_RECEIVED;
  599. }
  600. break;
  601. case USB_APP_SEND_COMPLETE:
  602. /* send data complete */
  603. g_phd_buffer_being_used = FALSE;/* release the phd_buffer */
  604. switch (phd_com_state)
  605. {
  606. case PHD_AG_STATE_CON_ASSOCIATING:
  607. {
  608. TIMER_OBJECT AssocTimerObject;
  609. /* 10 sec timer */
  610. AssocTimerObject.msCount = PHD_ASSOCIATION_TIMEOUT;
  611. AssocTimerObject.pfnTimerCallback =
  612. PHD_Association_Timer_Callback;
  613. /* start timer */
  614. timer_index = PHD_Add_Timer(&AssocTimerObject);
  615. break;
  616. }
  617. case PHD_AG_STATE_CON_ASSOC_CFG_SENDING_CONFIG:
  618. {
  619. TIMER_OBJECT ConfigTimerObject;
  620. phd_com_state =
  621. PHD_AG_STATE_CON_ASSOC_CFG_WAITING_APPROVAL;
  622. /* 10 sec timer */
  623. ConfigTimerObject.msCount = PHD_CONFIGURATION_TIMEOUT;
  624. ConfigTimerObject.pfnTimerCallback =
  625. PHD_Configuration_Timer_Callback;
  626. /* start timer */
  627. timer_index = PHD_Add_Timer(&ConfigTimerObject);
  628. break;
  629. }
  630. case PHD_AG_STATE_CON_DISASSOCIATING:
  631. {
  632. TIMER_OBJECT DissocTimerObject;
  633. /* 3 sec timer */
  634. DissocTimerObject.msCount = PHD_ASSOC_RELEASE_TIMEOUT;
  635. DissocTimerObject.pfnTimerCallback =
  636. PHD_Disassociation_Timer_Callback;
  637. /* start timer */
  638. timer_index = PHD_Add_Timer(&DissocTimerObject);
  639. break;
  640. }
  641. case PHD_AG_STATE_CON_ASSOC_OPERATING:
  642. {
  643. if(g_sent_resp_get_attr==TRUE)
  644. {
  645. /* attributes sent, ready to send measurements */
  646. g_phd_callback(controller_ID,
  647. APP_PHD_CONNECTED_TO_HOST);
  648. g_sent_resp_get_attr=FALSE;
  649. }
  650. else if(phd_com_state == PHD_AG_STATE_CON_ASSOC_OPERATING)
  651. {
  652. TIMER_OBJECT MsrTimerObject;
  653. /* 3 sec timer */
  654. MsrTimerObject.msCount = PHD_DEFAULT_RESPONSE_TIMEOUT;
  655. MsrTimerObject.pfnTimerCallback =
  656. PHD_Msr_Timer_Callback;
  657. /* start timer */
  658. timer_index = PHD_Add_Timer(&MsrTimerObject);
  659. }
  660. break;
  661. }
  662. } /* End switch(phd_com_state) */
  663. break;
  664. default:
  665. break;
  666. }/* End switch(event_type) */
  667. if(trans_event != 0xff)
  668. {
  669. uint_8 com_state;
  670. uint_8 transport_event = trans_event;
  671. /* get the received APDU */
  672. USB_APP_EVENT_DATA_RECEIVED *p_recv =
  673. (USB_APP_EVENT_DATA_RECEIVED *)val;
  674. APDU *p_apdu = (APDU *)(phd_buffer);
  675. if(trans_event == PHD_AG_EVT_TRANSPORT_APDU_RECEIVED)
  676. {
  677. /* apdu received from transport */
  678. transport_event = (uint_8)((p_apdu->choice >> UPPER_BYTE_SHIFT)
  679. & LOW_NIBBLE_MASK);
  680. }
  681. com_state = (uint_8)(phd_com_state & AG_PHD_STATE_MASK);
  682. if(phd_state_mc_func[com_state][transport_event] != NULL)
  683. { /* incase valid event then call the function */
  684. (void)phd_state_mc_func[com_state][transport_event]
  685. (controller_ID, p_apdu);
  686. }
  687. else
  688. {
  689. /* send error to app layer */
  690. g_phd_callback(controller_ID,APP_PHD_ERROR);
  691. }
  692. }
  693. /* Start next Receive */
  694. if(trans_event == PHD_AG_EVT_TRANSPORT_APDU_RECEIVED)
  695. (void)USB_Class_PHDC_Recv_Data(controller_ID, PHDC_BULK_OUT_QOS, NULL, 0);
  696. return;
  697. }
  698. /*****************************************************************************
  699. * Global Functions
  700. *****************************************************************************/
  701. /******************************************************************************
  702. *
  703. * @name PHD_Transport_Init
  704. *
  705. * @brief This function initializes the PHDC class layer and layers
  706. * below
  707. *
  708. * @param controller_ID : Controller ID
  709. * @param phd_callback : Callback function to register
  710. *
  711. * @return None
  712. *
  713. *****************************************************************************
  714. * Called by the application layer to initialize all the layers below it
  715. *****************************************************************************/
  716. uint_8 PHD_Transport_Init(
  717. uint_8 controller_ID, /* [IN] Controller ID */
  718. PHD_CALLBACK phd_callback /* [IN] Callback function to register */
  719. )
  720. {
  721. g_phd_callback = phd_callback;
  722. g_controllerID = controller_ID;
  723. return USB_Class_PHDC_Init(controller_ID, PHD_Callback, NULL);
  724. }
  725. /******************************************************************************
  726. *
  727. * @name PHD_Connect_to_Manager
  728. *
  729. * @brief This function sends the association request to the host
  730. *
  731. * @param controller_ID : Controller ID
  732. *
  733. * @return None
  734. *
  735. *****************************************************************************
  736. * This function is called by the application when enumeration is complete to
  737. * send the association request
  738. *****************************************************************************/
  739. void PHD_Connect_to_Manager(
  740. uint_8 controller_ID /* [IN] Controller ID */
  741. )
  742. {
  743. extern uint_8 const PHD_WSL_ASSOC_REQ[];
  744. if((phd_com_state == PHD_AG_STATE_CON_UNASSOCIATED) ||
  745. (phd_com_state == PHD_AG_STATE_CON_ASSOCIATING))
  746. {
  747. phd_com_state = PHD_AG_STATE_CON_ASSOCIATING;
  748. /* Send Assoc request to Manager */
  749. (void)USB_Class_PHDC_Send_Data(controller_ID, FALSE, 0, SEND_DATA_QOS,
  750. (uint_8_ptr)PHD_WSL_ASSOC_REQ, ASSOC_REQ_SIZE);
  751. }
  752. }
  753. /******************************************************************************
  754. *
  755. * @name PHD_Disconnect_from_Manager
  756. *
  757. * @brief This function sends the association release request to the
  758. * host
  759. *
  760. * @param controller_ID : Controller ID
  761. *
  762. * @return None
  763. *
  764. ****************************************************************************
  765. * Called by the application to send the assciation release request
  766. *****************************************************************************/
  767. void PHD_Disconnect_from_Manager(
  768. uint_8 controller_ID /* [IN] Controller ID */
  769. )
  770. {
  771. extern uint_8 const PHD_WSL_REL_REQ[];
  772. switch(phd_com_state)
  773. {
  774. case PHD_AG_STATE_CON_ASSOCIATING:
  775. phd_com_state = PHD_AG_STATE_CON_UNASSOCIATED;
  776. /* Send abort */
  777. PHD_Send_Abort_to_Manager(controller_ID,
  778. (uint_16)ABORT_REASON_UNDEFINED);
  779. break;
  780. case PHD_AG_STATE_CON_DISASSOCIATING:
  781. case PHD_AG_STATE_CON_UNASSOCIATED:
  782. /* No State Change in case of Dis-Associating or UnAssociated */
  783. break;
  784. default:
  785. phd_com_state = PHD_AG_STATE_CON_DISASSOCIATING;
  786. /* Send Association release to Manager */
  787. (void)USB_Class_PHDC_Send_Data(controller_ID, FALSE, 0,
  788. SEND_DATA_QOS, (uint_8_ptr)PHD_WSL_REL_REQ, REL_REQ_SIZE);
  789. break;
  790. }
  791. }
  792. /******************************************************************************
  793. *
  794. * @name PHD_Send_Abort_to_Manager
  795. *
  796. * @brief This function sends abort request to the host
  797. *
  798. * @param controller_ID : Controller ID
  799. * @param abort_reason : Reason for abort
  800. *
  801. * @return None
  802. *
  803. ****************************************************************************
  804. * Called by the application to send abort apdu
  805. *****************************************************************************/
  806. void PHD_Send_Abort_to_Manager (
  807. uint_8 controller_ID, /* [IN] Controller ID */
  808. uint_16 abort_reason /* [IN] Reason for abort */
  809. )
  810. {
  811. extern uint_8 const PHD_WSL_ABRT[];
  812. phd_com_state = PHD_AG_STATE_CON_UNASSOCIATED;
  813. assoc_retry_count = PHD_ASSOC_RETRY_COUNT;
  814. (void)memcpy(phd_buffer, PHD_WSL_ABRT, ABRT_SIZE);
  815. /* Update the abort reason */
  816. phd_buffer[4] = (uint_8)((abort_reason >> 8) & 0xFF);
  817. phd_buffer[5] = (uint_8)(abort_reason & 0xFF);
  818. /* Send Abort to Manager */
  819. (void)USB_Class_PHDC_Send_Data(controller_ID, FALSE, 0, SEND_DATA_QOS,
  820. (uint_8_ptr)&phd_buffer, ABRT_SIZE);
  821. }
  822. /******************************************************************************
  823. *
  824. * @name PHD_Send_Measurements_to_Manager
  825. *
  826. * @brief This function sends measurements to the host
  827. *
  828. * @param controller_ID : Controller ID
  829. *
  830. * @return None
  831. *
  832. *****************************************************************************
  833. * Called by the application to send the measurement data via event report
  834. *****************************************************************************/
  835. void PHD_Send_Measurements_to_Manager(
  836. uint_8 controller_ID /* [IN] Controller ID */ ,
  837. uint_8 qos
  838. )
  839. {
  840. if(phd_com_state == PHD_AG_STATE_CON_ASSOC_OPERATING)
  841. {
  842. USB_PACKET_SIZE buff_size = (USB_PACKET_SIZE)PHD_BUFF_SIZE;
  843. DisableInterrupts;
  844. #if (defined _MCF51MM256_H) || (defined _MCF51JE256_H)
  845. usb_int_dis();
  846. #endif
  847. /* if phd_buffer already in use, return */
  848. if(g_phd_buffer_being_used == TRUE)
  849. {
  850. EnableInterrupts;
  851. #if (defined _MCF51MM256_H) || (defined _MCF51JE256_H)
  852. usb_int_en();
  853. #endif
  854. return;
  855. }
  856. g_phd_buffer_being_used = TRUE;
  857. EnableInterrupts;
  858. #if (defined _MCF51MM256_H) || (defined _MCF51JE256_H)
  859. usb_int_en();
  860. #endif
  861. /* update measurements */
  862. PHD_Send_WSL_Measurements_to_Manager (controller_ID, &phd_buffer,
  863. (void*)&buff_size);
  864. /* send measurements */
  865. (void)USB_Class_PHDC_Send_Data(controller_ID, FALSE, 0, qos,
  866. (uint_8_ptr)phd_buffer, buff_size);
  867. }
  868. }
  869. /******************************************************************************
  870. *
  871. * @name PHD_Association_Timer_Callback
  872. *
  873. * @brief This function is called whenever association timeout occurs
  874. *
  875. * @param arg : Argument passed by Timer ISR (optional)
  876. *
  877. * @return None
  878. *
  879. *****************************************************************************
  880. * This function is called whenever association response is not received
  881. * within the association timeout time (10 seconds)
  882. *****************************************************************************/
  883. #ifdef TIMER_CALLBACK_ARG
  884. static void PHD_Association_Timer_Callback(void* arg)
  885. #else
  886. static void PHD_Association_Timer_Callback(void)
  887. #endif
  888. {
  889. #ifdef TIMER_CALLBACK_ARG
  890. UNUSED(arg)
  891. #endif
  892. /* Decrement association retry count */
  893. assoc_retry_count--;
  894. if(assoc_retry_count != 0)
  895. {
  896. /* connect to the manager if max retry count not reached */
  897. PHD_Connect_to_Manager(g_controllerID);
  898. }
  899. else
  900. {
  901. /* association failed for max retry count, so trasition to unassociated
  902. state, and reset the retry count. Now it is upto the application to
  903. start the association */
  904. /* Send abort */
  905. PHD_Send_Abort_to_Manager(g_controllerID,
  906. (uint_16) ABORT_REASON_RESPONSE_TIMEOUT);
  907. /* send error to app layer */
  908. g_phd_callback(g_controllerID, APP_PHD_ASSOCIATION_TIMEDOUT);
  909. }
  910. }
  911. /******************************************************************************
  912. *
  913. * @name PHD_Configuration_Timer_Callback
  914. *
  915. * @brief This function is called whenever configuration timeout
  916. * occurs
  917. *
  918. * @param arg : Argument passed by Timer ISR (optional)
  919. *
  920. * @return None
  921. *
  922. *****************************************************************************
  923. * This function is called whenever no response is received by the device
  924. * after sending the configuration event report within the configuration
  925. * timeout time
  926. *****************************************************************************/
  927. #ifdef TIMER_CALLBACK_ARG
  928. static void PHD_Configuration_Timer_Callback(void* arg)
  929. #else
  930. static void PHD_Configuration_Timer_Callback(void)
  931. #endif
  932. {
  933. #ifdef TIMER_CALLBACK_ARG
  934. UNUSED(arg)
  935. #endif
  936. /* Send abort */
  937. PHD_Send_Abort_to_Manager(g_controllerID,
  938. (uint_16) ABORT_REASON_RESPONSE_TIMEOUT);
  939. }
  940. /******************************************************************************
  941. *
  942. * @name PHD_Msr_Timer_Callback
  943. *
  944. * @brief This function is called whenever measurement timeout occurs
  945. *
  946. * @param arg : Argument passed by Timer ISR (optional)
  947. *
  948. * @return None
  949. *
  950. *****************************************************************************
  951. * This function is called whenever the response to the measurements is not
  952. * sent by the host within the specified time
  953. *****************************************************************************/
  954. #ifdef TIMER_CALLBACK_ARG
  955. static void PHD_Msr_Timer_Callback(void* arg)
  956. #else
  957. static void PHD_Msr_Timer_Callback(void)
  958. #endif
  959. {
  960. #ifdef TIMER_CALLBACK_ARG
  961. UNUSED(arg)
  962. #endif
  963. /* Send abort */
  964. PHD_Send_Abort_to_Manager(g_controllerID,
  965. (uint_16) ABORT_REASON_RESPONSE_TIMEOUT);
  966. }
  967. /******************************************************************************
  968. *
  969. * @name PHD_Disassociation_Timer_Callback
  970. *
  971. * @brief This function is called whenever disassociation timeout occurs
  972. *
  973. * @param arg : Argument passed by Timer ISR (optional)
  974. *
  975. * @return None
  976. *
  977. *****************************************************************************
  978. * This function is called whenever the timer expires after the disassociation
  979. * request is sent by the device i.e. no packet received in response to the
  980. * association release request
  981. *****************************************************************************/
  982. #ifdef TIMER_CALLBACK_ARG
  983. static void PHD_Disassociation_Timer_Callback(void* arg)
  984. #else
  985. static void PHD_Disassociation_Timer_Callback(void)
  986. #endif
  987. {
  988. #ifdef TIMER_CALLBACK_ARG
  989. UNUSED(arg)
  990. #endif
  991. /* Send abort */
  992. PHD_Send_Abort_to_Manager(g_controllerID,
  993. (uint_16) ABORT_REASON_RESPONSE_TIMEOUT);
  994. }
  995. /******************************************************************************
  996. *
  997. * @name PHD_Remove_Timer
  998. *
  999. * @brief This funtion calls the Timer api to remove the timer from
  1000. * the queue
  1001. *
  1002. * @param pindex : Pointer to Timer Index
  1003. *
  1004. * @return ERR_SUCCESS : Timer removed successfully
  1005. * ERR_INVALID_PARAM : Inavlid timer index
  1006. *
  1007. *****************************************************************************
  1008. * This function when called removes the timer specified by the timer index
  1009. *****************************************************************************/
  1010. static uint_8 PHD_Remove_Timer(uint_8_ptr pindex)
  1011. {
  1012. #if MAX_TIMER_OBJECTS
  1013. uint_8 err = (uint_8)ERR_INVALID_PARAM;
  1014. if(*pindex != INVALID_TIMER_VALUE)
  1015. {
  1016. (void)RemoveTimerQ(*pindex);
  1017. *pindex = INVALID_TIMER_VALUE;
  1018. err = ERR_SUCCESS;
  1019. }
  1020. return err;
  1021. #else
  1022. UNUSED(pindex)
  1023. return ERR_SUCCESS;
  1024. #endif
  1025. }
  1026. /******************************************************************************
  1027. *
  1028. * @name PHD_Add_Timer
  1029. *
  1030. * @brief This funtion calls the Timer api to add a timer to the queue
  1031. *
  1032. * @param pTimerObject : Pointer to Timer Object
  1033. *
  1034. * @return ERR_SUCCESS : Timer added successfully
  1035. * Others : In case of error
  1036. *
  1037. *****************************************************************************
  1038. * This function when called starts a timer
  1039. *****************************************************************************/
  1040. static uint_8 PHD_Add_Timer(PTIMER_OBJECT pTimerObject)
  1041. {
  1042. #if MAX_TIMER_OBJECTS
  1043. return AddTimerQ(pTimerObject);
  1044. #else
  1045. UNUSED(pTimerObject)
  1046. return ERR_SUCCESS;
  1047. #endif
  1048. }