/*************************************************************************** * Copyright (c) 2003-2006, Broadcom Corporation * All Rights Reserved * Confidential Property of Broadcom Corporation * * THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE * AGREEMENT BETWEEN THE USER AND BROADCOM. YOU HAVE NO RIGHT TO USE OR * EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT. * * $brcm_Workfile: $ * $brcm_Revision: $ * $brcm_Date: $ * * Module Description: * * Revision History: * * $brcm_Log: $ * ***************************************************************************/ #include "xds_ctrl.h" #include "ministd.h" #ifdef BCM_DEBUG #define XDS_DBG(x) BDBG_WRN(x) // #define XDS_DBG(x) ((void)0) #else #define XDS_DBG(x) ((void)0) #endif BDBG_MODULE(xds_ctrl); /* Summary: initialize XDS processing. Description: Setup XDS processing state. */ void xds_ctrl_init(xds_ctrl_t * p_xds /* uninitialized, allocated XDS reference */ ) { memset(p_xds,0,sizeof(xds_ctrl_t)); } /* Summary: Install XDS callback. Description: Install XDS callback. */ void xds_ctrl_set_cb(xds_ctrl_t * p_xds, /* uninitialized, allocated XDS reference */ xds_callback_t cb) /* XDS callback or NULL */ { uint32_t flags; flags = bos_enter_critical(); p_xds->xds_callback = cb; bos_exit_critical(flags); } /* Summary: Feed XDS characters. Description: Feed line all line 21 field 2 character pairs for XDS processing.. */ void xds_ctrl_feed(xds_ctrl_t * p_xds, unsigned char xds_char_0, unsigned char xds_char_1) { // XDS_DBG(("XDS(%d, 0x%02x, 0x%02x)\n",p_xds->xds_state,xds_char_0,xds_char_1)); if (p_xds->xds_state == eXDS_IDLE) { switch (xds_char_0) { case 0x01: case 0x02: p_xds->xds_class = eXDS_CLASS_CURRENT; break; case 0x03: case 0x04: p_xds->xds_class = eXDS_CLASS_FUTURE; break; case 0x05: case 0x06: p_xds->xds_class = eXDS_CLASS_CHANNEL; break; case 0x07: case 0x08: p_xds->xds_class = eXDS_CLASS_MISC; break; case 0x09: case 0x0A: p_xds->xds_class = eXDS_CLASS_PUBLIC; break; case 0x0B: case 0x0C: p_xds->xds_class = eXDS_CLASS_RESERVED; break; case 0x0D: case 0x0E: p_xds->xds_class = eXDS_CLASS_PRIVATE; break; default: /* do nothing */break; } switch (xds_char_0) { case 0x01: case 0x03: case 0x05: case 0x07: case 0x09: case 0x0B: case 0x0D: p_xds->xds_len = 0; p_xds->xds_checksum = xds_char_0 + xds_char_1; case 0x02: case 0x04: case 0x06: case 0x08: case 0x0a: case 0x0c: case 0x0e: /* continue start code should not allow type to change */ if (p_xds->xds_type != xds_char_1) p_xds->xds_len = 0; p_xds->xds_type = xds_char_1; p_xds->xds_state = eXDS_ACTIVE; break; } }else { /* Not XDS control code */ if ((xds_char_0 > 0x0f) && (xds_char_0 < 0x20)) { p_xds->xds_state = eXDS_IDLE; } else { p_xds->xds_checksum += xds_char_0; p_xds->xds_checksum += xds_char_1; /* check for end control code */ if (xds_char_0 == 0x0f) { /* validate checksum and send */ if ((p_xds->xds_checksum & 0x7F) == 0) { if (p_xds->xds_callback) { p_xds->xds_callback(p_xds->xds_class,p_xds->xds_type,p_xds->xds_data,p_xds->xds_len); }else { #ifdef BCM_DEBUG switch(p_xds->xds_class) { case eXDS_CLASS_CURRENT: if (p_xds->xds_type == eXDS_TYPE_PROG_CONT) { int i; static int adv[2] = { 0,0}; if ((adv[0] != p_xds->xds_data[0]) && (adv[1] != p_xds->xds_data[1])) { adv[0] = p_xds->xds_data[0]; adv[1] = p_xds->xds_data[1]; XDS_DBG(("Advisory: ")); for (i = 0; i < p_xds->xds_len; ++i) { XDS_DBG(("0x%02x ",p_xds->xds_data[i])); } XDS_DBG(("\n")); } } break; case eXDS_CLASS_CHANNEL: if (p_xds->xds_type == eXDS_CH_CALL_LETTERS) { p_xds->xds_data[p_xds->xds_len] = 0; XDS_DBG(("Channel: %s\n",(char*)p_xds->xds_data)); break; } else if (p_xds->xds_type == eXDS_CH_TSID) { p_xds->xds_data[p_xds->xds_len] = 0; XDS_DBG(("TSID: %s\n",(char*)p_xds->xds_data)); break; } case eXDS_CLASS_FUTURE: case eXDS_CLASS_MISC: case eXDS_CLASS_PUBLIC: case eXDS_CLASS_RESERVED: case eXDS_CLASS_PRIVATE: default: XDS_DBG(("XDS(T: %d, C: %d,0x%02x,0x%02x,%d)\n",p_xds->xds_type,p_xds->xds_class,p_xds->xds_data[0],p_xds->xds_data[1],p_xds->xds_len)); break; } #endif /* BCM_DEBUG */ } } p_xds->xds_state = eXDS_IDLE; } else { /* add data bytes */ if (p_xds->xds_len + 2 < MAX_MSG_LEN) { p_xds->xds_data[p_xds->xds_len++] = xds_char_0; p_xds->xds_data[p_xds->xds_len++] = xds_char_1; } } } } }