Add CMUX library.
authorKyoungyoup Park <gynaru.park@samsung.com>
Sat, 25 Aug 2012 08:41:02 +0000 (17:41 +0900)
committerKyoungyoup Park <gynaru.park@samsung.com>
Sat, 25 Aug 2012 08:41:02 +0000 (17:41 +0900)
Change-Id: I064ebaa4e00c1c01e9bf3cc6316182dddf1a0e84

CMakeLists.txt [changed mode: 0644->0755]
include/hal.h [changed mode: 0644->0755]
include/mux.h [new file with mode: 0755]
packaging/libtcore.spec [changed mode: 0644->0755]
src/hal.c [changed mode: 0644->0755]
src/mux.c [new file with mode: 0755]

old mode 100644 (file)
new mode 100755 (executable)
index 183e2f2..e003579
@@ -48,6 +48,7 @@ SET(SRCS
                src/co_sms.c
                src/co_phonebook.c
                src/co_gps.c
+               src/mux.c
 )
 
 
old mode 100644 (file)
new mode 100755 (executable)
index f08c692..5a54a54
@@ -36,7 +36,8 @@ enum tcore_hal_recv_data_type {
 enum tcore_hal_mode {
        TCORE_HAL_MODE_UNKNOWN,
        TCORE_HAL_MODE_AT,
-       TCORE_HAL_MODE_CUSTOM
+       TCORE_HAL_MODE_CUSTOM,
+    TCORE_HAL_MODE_TRANSPARENT
 };
 
 struct tcore_hal_operations {
@@ -54,6 +55,7 @@ char*        tcore_hal_get_name(TcoreHal *hal);
 
 TcoreAT*     tcore_hal_get_at(TcoreHal *hal);
 enum tcore_hal_mode tcore_hal_get_mode(TcoreHal *hal);
+TReturn        tcore_hal_set_mode(TcoreHal *hal, enum tcore_hal_mode mode);
 
 TReturn      tcore_hal_set_power(TcoreHal *hal, gboolean flag);
 
diff --git a/include/mux.h b/include/mux.h
new file mode 100755 (executable)
index 0000000..bd23b7d
--- /dev/null
@@ -0,0 +1,29 @@
+/*\r
+ * libtcore\r
+ *\r
+ * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.\r
+ *\r
+ * Contact: Arijit Sen <arijit.sen@samsung.com>\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __MUX_H__\r
+#define __MUX_H__\r
+\r
+void tcore_cmux_init(TcorePlugin *plugin, TcoreHal *h);\r
+\r
+void tcore_cmux_close();\r
+\r
+int tcore_cmux_rcv_from_hal(unsigned char *data, int len);\r
+#endif  /* __MUX_H__ */\r
old mode 100644 (file)
new mode 100755 (executable)
index a4a24b7..8c55c45
@@ -1,7 +1,7 @@
 #sbs-git:slp/pkgs/l/libtcore
 Name: libtcore
 Summary: Telephony-core library
-Version: 0.1.50
+Version: 0.1.51
 Release:    1
 Group:      System/Libraries
 License:    Apache
old mode 100644 (file)
new mode 100755 (executable)
index 872f578..9e7be96
--- a/src/hal.c
+++ b/src/hal.c
@@ -34,6 +34,8 @@
 #include "plugin.h"
 #include "user_request.h"
 #include "server.h"
+#include "mux.h"
+
 
 //#define IDLE_SEND_PRIORITY G_PRIORITY_DEFAULT
 #define IDLE_SEND_PRIORITY G_PRIORITY_HIGH
@@ -219,6 +221,16 @@ enum tcore_hal_mode tcore_hal_get_mode(TcoreHal *hal)
        return hal->mode;
 }
 
+TReturn tcore_hal_set_mode(TcoreHal *hal, enum tcore_hal_mode mode)
+{
+       if (!hal)
+               return TCORE_RETURN_EINVAL;
+       
+       hal->mode = mode;
+
+       return TCORE_RETURN_SUCCESS;
+}
+
 TReturn tcore_hal_link_user_data(TcoreHal *hal, void *user_data)
 {
        if (!hal)
@@ -316,16 +328,24 @@ TReturn tcore_hal_dispatch_response_data(TcoreHal *hal, int id,
                }
        }
        else {
-               p = tcore_queue_pop_by_id(hal->queue, id);
-               if (!p) {
-                       dbg("unknown pending (id=0x%x)", id);
-                       return TCORE_RETURN_PENDING_WRONG_ID;
-               }
-
-               tcore_pending_emit_response_callback(p, data_len, data);
-               tcore_user_request_unref(tcore_pending_ref_user_request(p));
-               tcore_pending_free(p);
+               if(hal->mode == TCORE_HAL_MODE_CUSTOM) {
+                       dbg("TCORE_HAL_MODE_CUSTOM");
+                       p = tcore_queue_pop_by_id(hal->queue, id);
+                       if (!p) {
+                               dbg("unknown pending (id=0x%x)", id);
+                               return TCORE_RETURN_PENDING_WRONG_ID;
+                       }
 
+                       tcore_pending_emit_response_callback(p, data_len, data);
+                       tcore_user_request_free(tcore_pending_ref_user_request(p));
+                       tcore_pending_free(p);
+               }
+               else if(hal->mode == TCORE_HAL_MODE_TRANSPARENT) {
+                       dbg("TCORE_HAL_MODE_TRANSPARENT");
+                       
+                       /* Invoke CMUX receive API for decoding */
+                       tcore_cmux_rcv_from_hal((unsigned char *)data, data_len);
+               }
                /* Send next request in queue */
                g_idle_add_full(IDLE_SEND_PRIORITY, _hal_idle_send, hal, NULL );
        }
diff --git a/src/mux.c b/src/mux.c
new file mode 100755 (executable)
index 0000000..2bec66c
--- /dev/null
+++ b/src/mux.c
@@ -0,0 +1,1374 @@
+/**\r
+ * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Contact: Arijit Sen <arijit.sen@samsung.com>\r
+ *\r
+ * PROPRIETARY/CONFIDENTIAL\r
+ *\r
+ * This software is the confidential and proprietary information of SAMSUNG ELECTRONICS ("Confidential Information").\r
+ * You shall not disclose such Confidential Information and shall\r
+ * use it only in accordance with the terms of the license agreement you entered into with SAMSUNG ELECTRONICS.\r
+ * SAMSUNG make no representations or warranties about the suitability\r
+ * of the software, either express or implied, including but not\r
+ * limited to the implied warranties of merchantability, fitness for a particular purpose, or non-infringement.\r
+ * SAMSUNG shall not be liable for any damages suffered by licensee as\r
+ * a result of using, modifying or distributing this software or its derivatives.\r
+ */\r
+\r
+#include <stdio.h>\r
+#include <string.h>\r
+#include <unistd.h>\r
+#include <stdlib.h>\r
+\r
+#include <glib.h>\r
+\r
+#include "tcore.h"\r
+\r
+#include "hal.h"\r
+#include "plugin.h"\r
+#include "user_request.h"\r
+#include "server.h"\r
+#include "mux.h"\r
+#include "core_object.h"\r
+\r
+/*For enabling MUX we need to set g_cmux_enable*/\r
+int g_cmux_enable = 1;\r
+\r
+/* Maximum Core objects per Logical HAL (indirectly per Channel) */\r
+#define CMUX_MAX_CORE_OBJECTS          3\r
+\r
+#define MAX_CMUX_BUFFER_SIZE           1024\r
+#define MAX_CHANNEL_SUPPORTED          8\r
+\r
+\r
+#define SABM  0x2F   \r
+#define UA      0x63    \r
+#define DM      0x0F    \r
+#define DISC   0x43   \r
+#define UIH     0xEF    \r
+#define UI       0x03    \r
+\r
+\r
+\r
+/* MUX CONTROL COMMANDS \r
+  * We are supporting only MSC command for phase 1\r
+  */\r
+#define  MSC   0xE3    //Modem Status Command\r
+#define  CLD  0xC3      //Multiplexer close down\r
+\r
+/*                  \r
+#define  PN                    //parameter negotiation\r
+#define  PSC                   //Power Saving Control\r
+#define TEST                   //Test Command\r
+#define  NSC                   //Non Supported Command Response\r
+#define  RPN                   //Remote Port Negotiation Command\r
+#define  RLS                   //Remote Line Status Command\r
+#define  SNC                   //Service Negotiation Command  */\r
+\r
+\r
+\r
+/* CMUX Channels [0-7] -\r
+  * Channel 0 - Control Channel for CMUX\r
+  * Channel 1 - CALL\r
+  * Channel 2 - SIM \r
+  * Channel 3 - SAT\r
+  * Channel 4 - SMS\r
+  * Channel 5 - SS\r
+  * Channel 6 - NETWORK\r
+  * Channel 7 - MODEM & PS\r
+  */\r
+typedef enum CMUX_Channels {\r
+       CMUX_CHANNEL_0,\r
+       CMUX_CHANNEL_1,\r
+       CMUX_CHANNEL_2,\r
+       CMUX_CHANNEL_3,\r
+       CMUX_CHANNEL_4,\r
+       CMUX_CHANNEL_5,\r
+       CMUX_CHANNEL_6,\r
+       CMUX_CHANNEL_7\r
+} CMUX_Channels;\r
+\r
+typedef enum MuxChannelState {\r
+       MUX_CHANNEL_CLOSED,\r
+       MUX_CHANNEL_SABM_SEND_WAITING_FOR_UA,\r
+       MUX_CHANNEL_ESTABLISHED,\r
+       MUX_CHANNEL_UA_NOT_RECEIVED_RETRY,\r
+       MUX_CHANNEL_DM_RECEIVED_CLOSING,\r
+       MUX_CHANNEL_DM_SEND,\r
+       MUX_CHANNEL_DISC_RECEIVED_CLOSING,\r
+       MUX_CHANNEL_DISC_SEND_WAITING_FOR_UA,\r
+       MUX_CHANNEL_UA_SEND_CLOSING,\r
+       MUX_CHANNEL_UA_RECEIVED,\r
+       MUX_CHANNEL_UA_SENDING,\r
+       \r
+} MuxChannelState;\r
+\r
+typedef enum MuxState {\r
+       MUX_NOT_INITIALIZED,\r
+       MUX_INITIALIZED,\r
+       MUX_CLOSED\r
+} MuxState;\r
+\r
+#define FIND_LENGTH(buf, hlen, Tlen)  do{ \\r
+                                                                                       if (*buf & 0x01) { \\r
+                                                                                               Tlen = *buf++ >>1; \\r
+                                                                                               hlen=6; \\r
+                                                                                               } \\r
+                                                                                               else { \\r
+                                                                                                       Tlen = *(buf + 0x01) << 7; \\r
+                                                                                                       Tlen = Tlen | (*buf & 0x7E) >> 1; \\r
+                                                                                                       hlen = 7; \\r
+                                                                                                       } \\r
+                                                                               } while(0)\r
+\r
+/*================= CRC TABLE=========================*/\r
+const unsigned char crctable[256] = { //reversed, 8-bit, poly=0x07\r
+       0x00, 0x91, 0xE3, 0x72, 0x07, 0x96, 0xE4, 0x75, 0x0E, 0x9F, 0xED, 0x7C, 0x09, 0x98, 0xEA, 0x7B,\r
+       0x1C, 0x8D, 0xFF, 0x6E, 0x1B, 0x8A, 0xF8, 0x69, 0x12, 0x83, 0xF1, 0x60, 0x15, 0x84, 0xF6, 0x67,\r
+       0x38, 0xA9, 0xDB, 0x4A, 0x3F, 0xAE, 0xDC, 0x4D, 0x36, 0xA7, 0xD5, 0x44, 0x31, 0xA0, 0xD2, 0x43,\r
+       0x24, 0xB5, 0xC7, 0x56, 0x23, 0xB2, 0xC0, 0x51, 0x2A, 0xBB, 0xC9, 0x58, 0x2D, 0xBC, 0xCE, 0x5F,\r
+       0x70, 0xE1, 0x93, 0x02, 0x77, 0xE6, 0x94, 0x05, 0x7E, 0xEF, 0x9D, 0x0C, 0x79, 0xE8, 0x9A, 0x0B,\r
+       0x6C, 0xFD, 0x8F, 0x1E, 0x6B, 0xFA, 0x88, 0x19, 0x62, 0xF3, 0x81, 0x10, 0x65, 0xF4, 0x86, 0x17,\r
+       0x48, 0xD9, 0xAB, 0x3A, 0x4F, 0xDE, 0xAC, 0x3D, 0x46, 0xD7, 0xA5, 0x34, 0x41, 0xD0, 0xA2, 0x33,\r
+       0x54, 0xC5, 0xB7, 0x26, 0x53, 0xC2, 0xB0, 0x21, 0x5A, 0xCB, 0xB9, 0x28, 0x5D, 0xCC, 0xBE, 0x2F,\r
+       0xE0, 0x71, 0x03, 0x92, 0xE7, 0x76, 0x04, 0x95, 0xEE, 0x7F, 0x0D, 0x9C, 0xE9, 0x78, 0x0A, 0x9B,\r
+       0xFC, 0x6D, 0x1F, 0x8E, 0xFB, 0x6A, 0x18, 0x89, 0xF2, 0x63, 0x11, 0x80, 0xF5, 0x64, 0x16, 0x87,\r
+       0xD8, 0x49, 0x3B, 0xAA, 0xDF, 0x4E, 0x3C, 0xAD, 0xD6, 0x47, 0x35, 0xA4, 0xD1, 0x40, 0x32, 0xA3,\r
+       0xC4, 0x55, 0x27, 0xB6, 0xC3, 0x52, 0x20, 0xB1, 0xCA, 0x5B, 0x29, 0xB8, 0xCD, 0x5C, 0x2E, 0xBF,\r
+       0x90, 0x01, 0x73, 0xE2, 0x97, 0x06, 0x74, 0xE5, 0x9E, 0x0F, 0x7D, 0xEC, 0x99, 0x08, 0x7A, 0xEB,\r
+       0x8C, 0x1D, 0x6F, 0xFE, 0x8B, 0x1A, 0x68, 0xF9, 0x82, 0x13, 0x61, 0xF0, 0x85, 0x14, 0x66, 0xF7,\r
+       0xA8, 0x39, 0x4B, 0xDA, 0xAF, 0x3E, 0x4C, 0xDD, 0xA6, 0x37, 0x45, 0xD4, 0xA1, 0x30, 0x42, 0xD3,\r
+       0xB4, 0x25, 0x57, 0xC6, 0xB3, 0x22, 0x50, 0xC1, 0xBA, 0x2B, 0x59, 0xC8, 0xBD, 0x2C, 0x5E, 0xCF\r
+};\r
+/*================= CRC TABLE=========================*/\r
+\r
+typedef struct cmux_channel {   \r
+       GSList *co; \r
+       TcoreHal *hal;\r
+       \r
+       MuxChannelState state; \r
+       CMUX_Channels ChannelId;\r
+       int  FrameType;\r
+       unsigned char  ExtBit;\r
+       unsigned char  CRBit;\r
+       unsigned char  pollFinalBit;\r
+\r
+#if 0\r
+       int  Len;\r
+\r
+       /*Information field*/\r
+       unsigned char *InfoField;\r
+\r
+#endif\r
+\r
+} CHANNEL;\r
+\r
+typedef gboolean (*mux_cb_func)(CHANNEL *channel_ptr);\r
+\r
+typedef struct cmux {\r
+       MuxState state;\r
+\r
+       CHANNEL *channelInfo[MAX_CHANNEL_SUPPORTED];\r
+       int isWaiting;\r
+       int pMsgLen;\r
+       int curMBufLen;\r
+\r
+       /* Plugin */\r
+       TcorePlugin *p;\r
+       \r
+       /* Physical HAL */\r
+       TcoreHal *phy_hal;\r
+\r
+       /* Modem Core Object */\r
+       CoreObject *modem_co;\r
+\r
+       mux_cb_func  cb_func;\r
+\r
+       /* Resolve Crash issue*/\r
+       int  Len;\r
+       /*Information field*/\r
+       unsigned char *InfoField;\r
+\r
+       unsigned char *muxTempBuffer;\r
+       unsigned char *muxMainBuffer;\r
+} MUX;\r
+\r
+/* Global pointer MUX Object pointer */\r
+MUX *MuxObjPtr = NULL;\r
+\r
+/* Global buffers for CMUX processing */\r
+//unsigned char Mux_buffer[MAX_CMUX_BUFFER_SIZE];\r
+//unsigned char muxTempBuffer[MAX_CMUX_BUFFER_SIZE];\r
+//unsigned char muxMainBuffer[MAX_CMUX_BUFFER_SIZE];\r
+\r
+/* CMUX mode of operation */\r
+int MUX_MODE = 0;      /* BASIC mode */\r
+\r
+struct cmux_channel_object {\r
+       char *channel_id_name;\r
+       char *Cobject_name[CMUX_MAX_CORE_OBJECTS];\r
+};\r
+\r
+/* Core Object names need to be verified, define a MACRO globally */\r
+struct cmux_channel_object cmux_channel_Cobject[] = {\r
+       {"channel_0",   {"control",             NULL,           NULL}},   \r
+       {"channel_1",   {"call",                        NULL,           NULL}},\r
+       {"channel_2",   {"sim",                 NULL,           NULL}},\r
+       {"channel_3",   {"sat",                 NULL,           NULL}},\r
+       {"channel_4",   {"umts_sms",            NULL,           NULL}},\r
+       {"channel_5",   {"ss",                  NULL,           NULL}},\r
+       {"channel_6",   {"umts_network",        NULL,           NULL}},\r
+       {"channel_7",   {"modem",               "umts_ps",      NULL}},\r
+};\r
+\r
+/* All the local functions declared below */\r
+static unsigned char calc_crc(unsigned char *header , int length);\r
+static int rcv_crc_check(unsigned char *data , unsigned char len,unsigned char RcvFCS);\r
+\r
+MUX *tcore_cmux_new(void);\r
+static void tcore_cmux_free();\r
+\r
+void tcore_cmux_link_core_object_hal(CMUX_Channels channel_id, TcorePlugin *plugin);\r
+static gboolean tcore_cmux_recv_mux_data(CHANNEL* channel_ptr);\r
+static void tcore_cmux_process_rcv_frame( unsigned char *data, int len);\r
+static void tcore_cmux_process_channel_data(CHANNEL *ChannelInfoPtr);\r
+static void tcore_cmux_control_channel_handle();\r
+static void tcore_cmux_flush_channel_data();\r
+\r
+void tcore_cmux_channel_init(CMUX_Channels channel_id);\r
+int tcore_cmux_close_channel(int channelID);\r
+       \r
+static unsigned char *tcore_encode_cmux_frame(unsigned char *data,\r
+                                                                                                       int length,\r
+                                                                                                       int channel_id,\r
+                                                                                                       int FrameType,\r
+                                                                                                       unsigned char EABit,\r
+                                                                                                       unsigned char CRBit,\r
+                                                                                                       unsigned char PFBit,\r
+                                                                                                       int *out_data_len);\r
+\r
+static TReturn tcore_cmux_hal_power(TcoreHal *h, gboolean flag)\r
+{\r
+       TcorePlugin *p = 0;\r
+       struct custom_data *user_data = 0;\r
+//     gboolean ret = 0;\r
+       dbg("Entry");\r
+\r
+       p = tcore_hal_ref_plugin(h);\r
+       if (!p) {\r
+               err("Plugin is undefined");\r
+               return TCORE_RETURN_FAILURE;\r
+       }\r
+\r
+       user_data = tcore_hal_ref_user_data(h);\r
+       if (!user_data) {\r
+               err("User data is undefined");\r
+               return TCORE_RETURN_FAILURE;\r
+       }\r
+\r
+       tcore_hal_set_power_state(h, TRUE);\r
+\r
+       dbg("Exit");\r
+       return TCORE_RETURN_SUCCESS;\r
+}\r
+\r
+static TReturn tcore_cmux_hal_send(TcoreHal *h, unsigned int data_len, void *data)\r
+{\r
+       unsigned char *send_data= NULL;\r
+       char *channel_name = NULL;\r
+       int channel_id = MAX_CHANNEL_SUPPORTED;\r
+       int len = 0;\r
+       int i = 0;\r
+\r
+       int ret;\r
+       dbg("Entry");\r
+       dbg("data: %s", (char *)data);\r
+\r
+       /* Check if Logical HAL is Powered ON */\r
+       if (tcore_hal_get_power_state(h) == FALSE) {\r
+               err("HAL is not Powered UP");\r
+               return TCORE_RETURN_FAILURE;\r
+       }\r
+\r
+       channel_name = tcore_hal_get_name(h);\r
+       dbg("HAL name: %s", channel_name)\r
+       if(channel_name) {\r
+               while(i < MAX_CHANNEL_SUPPORTED) {\r
+                       dbg("HAL name of Channels: %s",  cmux_channel_Cobject[i].channel_id_name);\r
+                       if (0 == strcmp((char *) cmux_channel_Cobject[i].channel_id_name, (char *)channel_name)) {\r
+                               channel_id = i;\r
+                               dbg("Found Channel ID: %d", channel_id);\r
+\r
+                               /* Free memory */\r
+                               free(channel_name);\r
+                               break;\r
+                       }\r
+                       i++;\r
+               }\r
+       }\r
+       else {\r
+               err("No name defined for HAL");\r
+               return TCORE_RETURN_FAILURE;\r
+       }\r
+\r
+       if(channel_id > MAX_CHANNEL_SUPPORTED) {\r
+               err("Failed to find Channel ID");\r
+               return TCORE_RETURN_FAILURE;\r
+       }\r
+       \r
+       /* Muxing operation and Frame creation */\r
+       /* Encoding frame */\r
+       send_data = tcore_encode_cmux_frame(data, data_len, channel_id, UIH, 1, 1, 0, &len);\r
+       if(NULL == send_data) {\r
+               err("Failed to encode");\r
+               return TCORE_RETURN_FAILURE;\r
+       }\r
+       \r
+       /* Directly send to Physical HAL */\r
+       ret = tcore_hal_send_data(MuxObjPtr->phy_hal, len, send_data);\r
+       \r
+       dbg("Exit");\r
+       return TCORE_RETURN_SUCCESS;\r
+}\r
+\r
+/* CMUX supported HAL (Logical HAL) operations */\r
+static struct tcore_hal_operations mux_hops =\r
+{\r
+       .power = tcore_cmux_hal_power,\r
+       .send = tcore_cmux_hal_send,\r
+};\r
+\r
+static gboolean tcore_cmux_recv_mux_data(CHANNEL *channel_ptr)\r
+{\r
+       TcoreHal *hal = NULL;\r
+       dbg("Entry");\r
+\r
+       /* Dereferencing HAL from Channel Pointer */\r
+       hal = channel_ptr->hal;\r
+       \r
+       dbg("Dispatching to logical HAL - hal: %x", hal);\r
+       tcore_hal_dispatch_response_data(hal, 0, MuxObjPtr->Len, MuxObjPtr->InfoField);\r
+\r
+       dbg("Exit");\r
+       return TRUE;\r
+}\r
+\r
+void tcore_cmux_link_core_object_hal(CMUX_Channels channel_id, TcorePlugin *plugin)\r
+{\r
+       TcoreHal *hal = NULL;\r
+       CoreObject *co = NULL;\r
+       int index;\r
+       dbg("Entry");\r
+\r
+       if(CMUX_CHANNEL_0 != channel_id) {\r
+               dbg("Normal channel [%d]", channel_id);\r
+               \r
+               /* Creating Logical HAL for Core Object - Mode - 'AT mode' */\r
+               hal = tcore_hal_new(plugin, cmux_channel_Cobject[channel_id].channel_id_name, &mux_hops, TCORE_HAL_MODE_AT);\r
+               dbg("hal: %p", hal);\r
+               \r
+               /* Update Logical HAL of CMUX Channel */\r
+               MuxObjPtr->channelInfo[channel_id]->hal = hal;\r
+               \r
+               index = 0;\r
+               while (NULL != cmux_channel_Cobject[channel_id].Cobject_name[index]) {\r
+                       /* Retrieving Core Object */\r
+                       dbg("Core Object: '%s'", cmux_channel_Cobject[channel_id].Cobject_name[index]);\r
+                       co = tcore_plugin_ref_core_object(plugin, cmux_channel_Cobject[channel_id].Cobject_name[index]);\r
+                       dbg("co: %p", co);\r
+\r
+                       if (0 == strcmp((const char *)cmux_channel_Cobject[channel_id].Cobject_name[index], "modem")) {\r
+                               MuxObjPtr->modem_co = co;\r
+                               dbg("'modem' Core object reference is stored");\r
+                       }\r
+\r
+                       /* Set Logical HAL to Core objects */\r
+                       tcore_object_set_hal(co, hal);\r
+\r
+                       /* Update Core Object list of CMUX Channel */\r
+                       MuxObjPtr->channelInfo[channel_id]->co = g_slist_append(MuxObjPtr->channelInfo[channel_id]->co, co);\r
+\r
+                       index++;\r
+               };\r
+       }\r
+       else {\r
+               /* Control Channel */\r
+               dbg("Control channel");\r
+               \r
+               /* Creating Logical HAL for Core Object - Mode - 'AT mode' */\r
+               hal = tcore_hal_new(plugin, cmux_channel_Cobject[channel_id].channel_id_name, &mux_hops, TCORE_HAL_MODE_AT);\r
+               dbg("hal: %p", hal);\r
+               \r
+               /* Update Logical HAL of CMUX Channel */\r
+               MuxObjPtr->channelInfo[channel_id]->hal = hal;\r
+       }\r
+\r
+       /* Set Logical HAL Power State to TRUE */\r
+       tcore_hal_set_power_state(hal, TRUE);\r
+       dbg("HAL Power is SET");\r
+       \r
+       dbg("Exit");\r
+       return;\r
+}\r
+\r
+/************************************************************\r
+\r
+Here we initialize the MUX\r
+\r
+************************************************************/\r
+MUX *tcore_cmux_new(void)\r
+{\r
+       MUX *p = NULL;\r
+       int i = 0;\r
+       dbg("Entry");\r
+       \r
+       p = (MUX*)calloc(sizeof(MUX), 1);\r
+       if (!p) {\r
+               err("Failed to allocate memory");\r
+               return NULL;\r
+       }\r
+\r
+       p->InfoField = (unsigned char *)calloc(MAX_CMUX_BUFFER_SIZE, 1);        \r
+       if (!p->InfoField) {\r
+               err("Failed to allocate memory for info field");\r
+               goto ERROR;\r
+       }\r
+       \r
+       p->muxTempBuffer = (unsigned char *)calloc(MAX_CMUX_BUFFER_SIZE, 1);    \r
+       if (!p->InfoField) {\r
+               err("Failed to allocate memory for info field");\r
+               goto ERROR;\r
+       }\r
+       \r
+       p->muxMainBuffer = (unsigned char *)calloc(MAX_CMUX_BUFFER_SIZE, 1);\r
+       if (!p->InfoField) {\r
+               err("Failedto allocate memory for info field");\r
+               goto ERROR;\r
+       }\r
+       \r
+       p->state = MUX_NOT_INITIALIZED;\r
+\r
+       for(i = 0 ; i < MAX_CHANNEL_SUPPORTED ; i++) {\r
+               p->channelInfo[i] = (CHANNEL*)calloc(sizeof(CHANNEL) , 1);\r
+               /* Check for Memory allocation failure */\r
+               if(!p->channelInfo[i]) {\r
+                       err("Failed to allocate memory for info field");\r
+                       goto ERROR;\r
+               }\r
+       }\r
+\r
+       dbg("Exit");\r
+       return p;\r
+\r
+ERROR:\r
+       /* Free allocated memory */\r
+       if(p) {\r
+               if(p->InfoField) {\r
+                       free(p->InfoField);\r
+               }\r
+               \r
+               if(p->muxTempBuffer) {\r
+                       free(p->muxTempBuffer);\r
+               }\r
+               \r
+               if(p->muxMainBuffer) {\r
+                       free(p->muxMainBuffer);\r
+               }\r
+\r
+               for(i = 0; i < MAX_CHANNEL_SUPPORTED ; i++) {\r
+                       if(p->channelInfo[i]) {\r
+                               free(p->channelInfo[i]);\r
+                       }\r
+               }\r
+\r
+               free(p);\r
+       }\r
+\r
+       err("Exit");\r
+       return NULL;\r
+}\r
+\r
+\r
+\r
+/************************************************************\r
+This function is used while encoding .\r
+There is seperate function for decoding CRC\r
+Frame Checking Sequence Field\r
+************************************************************/\r
+static unsigned char calc_crc (unsigned char *header , int length)\r
+{\r
+       unsigned char FCS=0xFF; /*Init*/\r
+       \r
+       /*len is the number of bytes in the message, p points to message*/\r
+       while (length--) {\r
+               FCS = crctable[FCS ^ *header++];\r
+       }\r
+       \r
+       /*Ones complement*/\r
+       return (0xFF-FCS);\r
+}\r
+\r
+/************************************************************\r
+Function name : tcore_encode_cmux_frame\r
+\r
+\r
+************************************************************/\r
+static unsigned char *tcore_encode_cmux_frame(unsigned char *data,\r
+                                                                                               int length,\r
+                                                                                               int channel_id,\r
+                                                                                               int FrameType,\r
+                                                                                               unsigned char EABit,\r
+                                                                                               unsigned char CRBit,\r
+                                                                                               unsigned char PFBit,\r
+                                                                                               int *out_data_len)\r
+{\r
+       int tLength=0, frameLen=0;\r
+       int crc_len =0;\r
+       dbg("Entry");\r
+\r
+\r
+       /* Flush channel data */\r
+       tcore_cmux_flush_channel_data();\r
+\r
+       if(length > MAX_CMUX_BUFFER_SIZE ){\r
+               err("Length - %d  exceeds the limit", length);\r
+               return NULL;\r
+               }\r
+       //flag Octet\r
+       MuxObjPtr->InfoField[tLength++] = (char)0xF9;\r
+\r
+       if(0x00 == MUX_MODE) {          /* BASIC */\r
+               /* EA: Extension Bit\r
+               * C/R: Command Response\r
+               */\r
+               MuxObjPtr->InfoField[tLength] = MuxObjPtr->InfoField[tLength] | ((EABit & 0x01) | ((CRBit << 1) & 0x02)); \r
+\r
+               /* DLCI: Data Link Connection Identifier */\r
+               /* Check if the channel is within range */\r
+               if(channel_id < MAX_CHANNEL_SUPPORTED && channel_id >=0) {\r
+                       dbg("Channel ID: %d", channel_id);\r
+                       MuxObjPtr->InfoField[tLength] = MuxObjPtr->InfoField[tLength]|((unsigned char) channel_id << 2);\r
+               }\r
+               else {\r
+                       err("Channel is out of range[0-8]");\r
+                       return NULL;\r
+               }\r
+               tLength++;\r
+\r
+               /* Control Field\r
+                 * The content of the control field defines the type of frame.\r
+                 * ***************************************************************\r
+                 * Frame Type                                                                          0 1 2 3  4   5 6 7\r
+                 * SABM (Set Asynchronous Balanced Mode)                               1 1 1 1 P/F 1 0 0\r
+                 * UA (Unnumbered Acknowledgement)                                     1 1 0 0 P/F 1 1 0\r
+                 * DM (Disconnected Mode)                                                              1 1 1 1 P/F 0 0 0\r
+                 * DISC (Disconnect)                                                                   1 1 0 0 P/F 0 1 0\r
+                 * UIH (Unnumbered Information with Header check)                      1 1 1 1 P/F 1 1 1\r
+                 ****************************************************************/\r
+               if(PFBit) {\r
+                       MuxObjPtr->InfoField[tLength++] = FrameType |0x10;\r
+               }\r
+               else {\r
+                       MuxObjPtr->InfoField[tLength++] = FrameType;\r
+               }\r
+\r
+               /* 5.2.1.5 Length Indicator */\r
+               if (length < 128) {\r
+                       //length =(char)length <<1|0x01;\r
+                       MuxObjPtr->InfoField[tLength++] =(char)length <<1|0x01;\r
+                       \r
+                       /* CRC calculatable length */\r
+                       crc_len = 3;\r
+               }\r
+               else {\r
+                       MuxObjPtr->InfoField[tLength++] = (char)(length << 1);  //Need to change\r
+                       MuxObjPtr->InfoField[tLength++] = (char)(length >> 7);  //Need to change \r
+\r
+                       /* CRC calculatable length */\r
+                       crc_len = 4;\r
+               }\r
+\r
+               /* We need to divide the frames into maximum frame length supported by IMC.\r
+               * If IMC supports length according to 27.010 , we can send max of 16,384 bytes.\r
+               * Need to discuss with IMC.\r
+               */\r
+\r
+               /* 5.2.1.4 Information Field*/\r
+               if(length >0) {\r
+                       dbg("MEMCPY :length= %d", length);\r
+                       memcpy((MuxObjPtr->InfoField + tLength),data, length);\r
+                       dbg("MEMCPY :DONE");\r
+                       tLength += length;\r
+               }\r
+               else {\r
+                       dbg("info field length is zero");\r
+               }\r
+\r
+               /*5.2.1.6 Frame Checking Sequence Field (FCS)*/\r
+               MuxObjPtr->InfoField[tLength++] = calc_crc(MuxObjPtr->InfoField+1, crc_len);\r
+\r
+               /*Flag Octet*/\r
+               MuxObjPtr->InfoField[tLength++] = 0xF9;\r
+\r
+               frameLen = tLength;\r
+       }\r
+       else if (0x01 == MUX_MODE) {                    /* TBD MUX_MODE_ADVANCE */\r
+               dbg("For PHASE 2 !!");\r
+       }\r
+\r
+       *out_data_len = frameLen;\r
+       dbg("*out_data_len: %d", *out_data_len);\r
+\r
+       dbg("Exit frameLen: %d", frameLen);\r
+       return MuxObjPtr->InfoField;\r
+}\r
+\r
+\r
+static int rcv_crc_check(unsigned char *data , unsigned char len,unsigned char RcvFCS)\r
+{\r
+       unsigned char FCS = 0xFF;\r
+\r
+       /* 'len' is the number of bytes in the message, 'p' points to message */\r
+       while (len--) {\r
+               //input =(char) *data++;\r
+               FCS = crctable[FCS ^ *data++];\r
+       }\r
+       \r
+       /*Ones complement*/\r
+       FCS = crctable[FCS ^ RcvFCS];\r
+       \r
+       /* 0xCF is the reversed order of 11110011 */\r
+       if (0xCF == FCS) {              /* FCS is OK */\r
+               return 1;\r
+       }\r
+       else {                          /* FCS is NOT OK */\r
+               return 0;\r
+       }\r
+}\r
+\r
+/************************************************************\r
+Function name : tcore_cmux_flush_channel_data\r
+\r
+\r
+************************************************************/\r
+static void tcore_cmux_flush_channel_data()\r
+{\r
+       dbg("Entry");\r
+\r
+       MuxObjPtr->Len =0x0;\r
+       memset(MuxObjPtr->InfoField, 0x0, MAX_CMUX_BUFFER_SIZE);\r
+       \r
+       dbg("Exit");\r
+       return;\r
+}\r
+\r
+/************************************************************\r
+Function name : mux_control_chnl_handle\r
+\r
+\r
+************************************************************/\r
+static void tcore_cmux_control_channel_handle()\r
+{\r
+       unsigned char Cmdtype;\r
+       int MsgLen =0;\r
+       unsigned char *PtrMsgStart =NULL;\r
+       dbg("Entry");\r
+       \r
+       /* 5.4.6.1 Message format\r
+         * All messages sent between the multiplexers conform to the following type, length, value format:\r
+         * Type Length Value 1 Value2  \85\r
+         */\r
+       if (MuxObjPtr->Len > 0) {   \r
+               PtrMsgStart = MuxObjPtr->InfoField ;\r
+               Cmdtype = MuxObjPtr->InfoField[0];\r
+               /* The EA bit is an extension bit. The EA bit is set to 1 in the last octet of the sequence; \r
+                 * in other octets EA is set to 0.\r
+                 * \r
+                 * Search for the last octet\r
+                 */\r
+               while( (*PtrMsgStart++ & 0x01)) {       //TBD\r
+                       MsgLen ++;\r
+               }\r
+               \r
+               if((Cmdtype & 0x02) == 0x02) {  //This is a command Request\r
+                       //Modem Status Command\r
+                       if(Cmdtype == MSC )     {     \r
+                               dbg("Modem Status Command");\r
+                       }\r
+                       else if(Cmdtype == CLD) {       //Modem Status Command\r
+                               tcore_cmux_close();\r
+                       }\r
+#if 0          /* We will be supporting the commands in Phase 2 */\r
+                       else if(Cmdtype == PN) //Modem Status Command\r
+                       {\r
+                       }\r
+#endif         /* We will be supporting the commands in Phase 2 */\r
+               }\r
+       }\r
+       else {\r
+               err("Frame length is less than ZERO");\r
+       }\r
+\r
+       dbg("Exit");\r
+       return;\r
+}\r
+\r
+/************************************************************\r
+Function name : tcore_cmux_process_channel_data\r
+\r
+Process the channel data\r
+************************************************************/\r
+static void tcore_cmux_process_channel_data(CHANNEL *ChannelInfoPtr)\r
+{\r
+       int frameType;\r
+       int ChannelId;\r
+       int len;\r
+       int ret;\r
+       unsigned char * send_data=NULL;\r
+       static int count = 0;\r
+       dbg("Entry");\r
+\r
+       ChannelId = ChannelInfoPtr->ChannelId;\r
+       dbg("Channel ID: %d", ChannelId);\r
+       \r
+       ChannelInfoPtr = MuxObjPtr->channelInfo[ChannelId];\r
+\r
+       frameType = ChannelInfoPtr->FrameType & 0xEF;\r
+       dbg("frameType: 0x%x", frameType);\r
+       \r
+       switch(frameType)\r
+       {\r
+               case UI:\r
+               case UIH:\r
+               {\r
+                       dbg("Received UIH Frame");\r
+                       if(0 == ChannelId) {\r
+                               /*this is control info*/\r
+                               dbg("Control information");\r
+                               tcore_cmux_control_channel_handle();\r
+                       }\r
+                       else {\r
+                               //put in the logical HAL queue\r
+                               //this goes to the Cobject\r
+\r
+                               //ChannelInfoPtr->Len = ChannelInfoPtr->Len;\r
+                               //memcpy(ChannelInfoPtr->InfoField, ChannelInfoPtr->InfoField, ChannelInfoPtr->Len);\r
+                               \r
+                               tcore_cmux_recv_mux_data(ChannelInfoPtr);\r
+                       }\r
+                       break;\r
+               }\r
+               case UA:\r
+               {\r
+                       dbg("Received UA Frame");\r
+                       dbg("ChannelInfoPtr->state: %d", ChannelInfoPtr->state);\r
+                       if(MUX_CHANNEL_SABM_SEND_WAITING_FOR_UA == ChannelInfoPtr->state) {\r
+                               ChannelInfoPtr->state = MUX_CHANNEL_ESTABLISHED;\r
+\r
+                               count++;\r
+                               dbg("Count: %d", count);\r
+                               if(MAX_CHANNEL_SUPPORTED == count) {\r
+                                       /* Indicate to CoreObject */\r
+                                       CoreObject *co = NULL;\r
+\r
+                                       /* 'modem' Core Object */\r
+                                       co = MuxObjPtr->modem_co;\r
+                                       if(NULL == co) {\r
+                                               err("'modem' Core object is not present");\r
+                                               return;\r
+                                       }\r
+\r
+                                       /* Emit callback */\r
+                                       dbg("Emit Core object callback");\r
+                                       tcore_object_emit_callback(co, "CMUX-UP", NULL);\r
+                                       dbg("Emitted Core object callback");\r
+                                       count = 0;\r
+                               }\r
+                       }\r
+                       else if(MUX_CHANNEL_DISC_SEND_WAITING_FOR_UA == ChannelInfoPtr->state) {\r
+                               ChannelInfoPtr->state = MUX_CHANNEL_CLOSED;\r
+\r
+                               if(0 == ChannelId) {\r
+                                       MuxObjPtr->state = MUX_CLOSED;\r
+                                       tcore_cmux_close();\r
+                               }\r
+                       }\r
+                       else  {\r
+                               err("Received UA in wrong state!!!");\r
+                       }\r
+                       break;\r
+               }\r
+               case DM:\r
+               {\r
+                       /* 5.4.1 DLC Establishment : If the responding station is not ready or unwilling\r
+                         * to establish the particular DLC it will reply with a DM frame with the\r
+                         * F-bit set to 1.\r
+                         */\r
+                       dbg("Received DM Frame");\r
+                       if((MUX_CHANNEL_ESTABLISHED == ChannelInfoPtr->state)\r
+                               || (MUX_CHANNEL_SABM_SEND_WAITING_FOR_UA == ChannelInfoPtr->state)) {\r
+                                       ChannelInfoPtr->state = MUX_CHANNEL_CLOSED;\r
+                       }\r
+                       tcore_cmux_flush_channel_data();\r
+\r
+                       break;\r
+               }\r
+               case DISC:\r
+               {\r
+                       dbg("Received DISC Frame");\r
+                       if(0 == ChannelInfoPtr->pollFinalBit) {\r
+                               /* In the case where a SABM or DISC command with the P bit set to 0 is received then \r
+                                 * the received frame shall be discarded.\r
+                                 */\r
+                               tcore_cmux_flush_channel_data();\r
+                       }\r
+                       else {\r
+                                       if(MUX_CHANNEL_CLOSED == ChannelInfoPtr->state) {\r
+                                       //If a DISC command is received while in disconnected mode a DM response should be sent\r
+                                       /* Encoding frame */\r
+                                       send_data = tcore_encode_cmux_frame(NULL, 0, ChannelId, DM, 1, 1, 1, &len);\r
+                       \r
+                                       }\r
+                                       else {   //send Unnumbered Acknowledgement\r
+                                       send_data =     tcore_encode_cmux_frame(NULL,0, ChannelId,  UA, 1, 1, 1,&len);\r
+                                       }\r
+\r
+                                       if(0 == len) {\r
+                                       err("Failed to encode");\r
+                                       return;\r
+                                               }\r
+                                       /* Directly send to Physical HAL */\r
+                                       ret = tcore_hal_send_data(MuxObjPtr->phy_hal,len, send_data);\r
+                                       \r
+                                       /*5.3.4 Disconnect (DISC) command: DISC command sent at DLCI 0 have the same \r
+                                       meaning as the Multiplexer Close Down command */\r
+                                       tcore_cmux_flush_channel_data();        \r
+                                       if(0 == ChannelId) {\r
+                                               MuxObjPtr->state =MUX_CLOSED;\r
+                                               tcore_cmux_close();\r
+                                       }\r
+                       }\r
+                       break;\r
+               }       \r
+               case SABM:\r
+               {\r
+                       dbg("Received SABM Frame");\r
+                       if(0 == ChannelInfoPtr->pollFinalBit) {\r
+                               /*In the case where a SABM or DISC command with the P bit set to 0 is received then \r
+                               the received frame shall be discarded. */\r
+                               //flush_rcv_data();\r
+                               tcore_cmux_flush_channel_data();\r
+                       }\r
+                       else {\r
+                               send_data = tcore_encode_cmux_frame(NULL,0, ChannelId,  UA, 1, 1, 1,&len); \r
+                               /* Directly send to Physical HAL */\r
+                                       ret = tcore_hal_send_data(MuxObjPtr->phy_hal, len,send_data);\r
+\r
+                               if(ChannelInfoPtr->state != MUX_CHANNEL_ESTABLISHED) {\r
+                                       ChannelInfoPtr->state = MUX_CHANNEL_ESTABLISHED;\r
+                               }\r
+                       } \r
+                       break;\r
+               }\r
+       }\r
+\r
+       return ;\r
+}\r
+\r
+/**********************************************\r
+\r
+Function name :tcore_cmux_rcv_from_hal\r
+\r
+This should be a callback from Physical HAL.\r
+DATA Received from CP side.\r
+\r
+***********************************************/\r
+static void tcore_cmux_process_rcv_frame( unsigned char *data, int len)\r
+{\r
+       unsigned char *PtrFrameProcess =data;\r
+       unsigned char *PtrBufStart = data;\r
+\r
+       CHANNEL *ch =NULL;\r
+       unsigned char ChannelId;\r
+       int hlen;\r
+       dbg("Entry");\r
+\r
+       tcore_cmux_flush_channel_data();\r
+\r
+       /* Get the Channel ID : 1st byte will be flag (F9)..Flag checking is already done.*/\r
+       if((ChannelId = ((*++PtrFrameProcess  >> 2)& 0x3F)) < MAX_CHANNEL_SUPPORTED) {   //max channel is 8\r
+\r
+               ch = MuxObjPtr->channelInfo[ChannelId];\r
+\r
+               ch->ChannelId = ChannelId;\r
+\r
+               //get the EA bit\r
+               ch->ExtBit = *PtrFrameProcess  & 0x01;\r
+\r
+               //get the CR bit\r
+               ch->CRBit = (*PtrFrameProcess ++ >> 1) & 0x01;\r
+\r
+               //get the Frame Type\r
+               ch->FrameType = *PtrFrameProcess  ++;\r
+\r
+               //get the poll/Final bit\r
+               ch->pollFinalBit = (ch->FrameType & 0x10)>> 4;\r
+\r
+               //get the length . TBD\r
+               if(*PtrFrameProcess  & 0x01) {                  //if len <127\r
+                       MuxObjPtr->Len = *PtrFrameProcess ++ >> 1;\r
+                       hlen = 3;\r
+               }\r
+               else {\r
+                       MuxObjPtr->Len = *(PtrFrameProcess +1) << 7;\r
+                       MuxObjPtr->Len = MuxObjPtr->Len | ((* PtrFrameProcess ++ & 0xFE) >> 1);\r
+                       hlen = 4;\r
+                       PtrFrameProcess++;\r
+               }\r
+               \r
+               /* Copy received information field */\r
+               dbg("MEMCPY :length= %d", MuxObjPtr->Len);\r
+               memcpy(MuxObjPtr->InfoField, PtrFrameProcess, MuxObjPtr->Len);\r
+               dbg("MEMCPY :Done");\r
+               PtrFrameProcess = PtrFrameProcess + MuxObjPtr->Len;\r
+\r
+               //CRC check of the header\r
+               if (rcv_crc_check(PtrBufStart+1, hlen, *PtrFrameProcess)) {\r
+\r
+                       dbg("Calling tcore_cmux_process_channel_data");\r
+                       tcore_cmux_process_channel_data(ch);\r
+               }\r
+               else {\r
+                       err("CRC check of the header FAILED.. Drop the packet !!");\r
+               }\r
+       }       \r
+       else {\r
+               err("Incorrect channel... Drop the packet !!");\r
+       }\r
+\r
+       dbg("Exit");\r
+       return;\r
+}\r
+\r
+/**********************************************\r
+\r
+Function name :tcore_cmux_rcv_from_hal\r
+\r
+This should be a callback from Physical HAL.\r
+DATA Received from CP side.\r
+\r
+***********************************************/\r
+int tcore_cmux_rcv_from_hal(unsigned char *data, int len)\r
+{\r
+       unsigned char *buf =data;\r
+       int count =0, i =0;\r
+       int alen =0; //actual length\r
+       \r
+       unsigned char *muxTempBuffer = MuxObjPtr->muxTempBuffer;\r
+       unsigned char *muxMainBuffer = MuxObjPtr->muxMainBuffer;\r
+\r
+       int Tlen = 0;                   /* Total length                   */\r
+       int hlen = 0;                   /* Header length                  */\r
+       int currentFlen = 0;    /* Current Frame length    */   \r
+       int pLen = 0;           /* pending length in array */ \r
+       \r
+       dbg("Entry");\r
+\r
+#if 1\r
+       //testing\r
+       dbg("len: %d ", len);\r
+       {\r
+               int i=0;\r
+               for(i = 0; i < len ; i++) {\r
+                       msg("%02x", data[i]);\r
+               }\r
+       }\r
+#endif\r
+\r
+       if (len > MAX_CMUX_BUFFER_SIZE){\r
+               err("len - %d is more than MAX limit !!" ,len);\r
+               return 0;\r
+               }\r
+               \r
+\r
+       if( (len > 0 ) && (data != NULL)) {\r
+               if(MuxObjPtr->isWaiting) {\r
+                       //* Checking if Frame fully contains F9 or not. If only F9,then reject, esle process.\r
+                       while(*buf++ == 0xF9) {\r
+                               count++;\r
+                       }\r
+\r
+                       if (count == len) {     // In case all are F9 \r
+                               err("Not a valid frame");\r
+                               return 0;\r
+                       }\r
+                       dbg("MEMCPY :MuxObjPtr->curMBufLen: %d & len = %d", MuxObjPtr->curMBufLen,len);\r
+                       memcpy((muxMainBuffer + MuxObjPtr->curMBufLen),data,len);\r
+                       dbg("MEMCPY :DONE");\r
+                       MuxObjPtr->curMBufLen = MuxObjPtr->curMBufLen + len;\r
+\r
+                       if(MuxObjPtr->pMsgLen <= len) {\r
+                               MuxObjPtr->isWaiting =0;\r
+                               tcore_cmux_rcv_from_hal(muxMainBuffer,MuxObjPtr->curMBufLen);\r
+                       }\r
+                       else {\r
+                               MuxObjPtr->pMsgLen = MuxObjPtr->pMsgLen - len;\r
+                               dbg("Still waiting for the complete frame!!!");\r
+                       }\r
+               }\r
+               else {\r
+                       if(*buf ==0xF9) {       // start flag present\r
+                               //remove extra flags\r
+                               while(*++buf == 0xF9) {\r
+                                       count++;\r
+                               }\r
+\r
+                               //check if received data has atleast three octets between flags\r
+                               for(i = 0; ( (i<3) && (*(buf+i)!=0xF9)); i++);\r
+\r
+                               if((i<3) || (count == (len-1))) {       // In case all are F9 or three octets between falgs not found\r
+                                       err("Not a valid frame");\r
+                                       return 0;\r
+                               }\r
+\r
+                               alen = len - count;\r
+                               memset(muxTempBuffer, 0x0, MAX_CMUX_BUFFER_SIZE);\r
+                               dbg("MEMCPY :alen= %d", alen);\r
+                               memcpy(muxTempBuffer, data + count, alen);\r
+                               dbg("MEMCPY :DONE");\r
+                               buf = muxTempBuffer + 3;\r
+\r
+                               //find the info length field of the current frame\r
+                               FIND_LENGTH(buf, hlen, Tlen);\r
+\r
+                               //calculate the current frame length including the headers\r
+                               currentFlen = hlen +Tlen;\r
+                               memset(muxMainBuffer, 0x0, MAX_CMUX_BUFFER_SIZE);\r
+\r
+                               if(currentFlen==alen) { //Only 1 frame is received and its a complete frame\r
+                                       if(muxTempBuffer[currentFlen-0x01] == 0xF9) {\r
+                                               dbg("MEMCPY :currentFlen= %d", currentFlen);\r
+                                               memcpy(muxMainBuffer,muxTempBuffer,currentFlen);\r
+                                               dbg("MEMCPY :DONE");\r
+                                               tcore_cmux_process_rcv_frame(muxMainBuffer ,currentFlen);\r
+                                               //initialze the main buffer\r
+                                               memset(muxMainBuffer, 0x0, MAX_CMUX_BUFFER_SIZE);\r
+                                       }\r
+                                       else {\r
+                                               err("End flag missing!!!");\r
+                                               return 0;\r
+                                       }\r
+                               }\r
+                               else if(currentFlen < alen) {           //more than one frame\r
+                                       if(muxTempBuffer[currentFlen-0x01] == 0xF9) {\r
+                                               dbg("MEMCPY :currentFlen= %d", currentFlen);\r
+                                               memcpy(muxMainBuffer,muxTempBuffer,currentFlen);\r
+                                               dbg("MEMCPY :DONE");\r
+                                               tcore_cmux_process_rcv_frame(muxMainBuffer ,currentFlen);\r
+\r
+                                               //initialze the main buffer\r
+                                               memset(muxMainBuffer, 0x0, MAX_CMUX_BUFFER_SIZE);\r
+\r
+                                               muxMainBuffer[0]=0xF9;\r
+                                               pLen = alen - currentFlen;\r
+                                               dbg("MEMCPY :pLen= %d", pLen);\r
+                                               memcpy((muxMainBuffer + 0x01), (muxTempBuffer + currentFlen), pLen);\r
+                                               dbg("MEMCPY :DONE");\r
+                                               tcore_cmux_rcv_from_hal( muxMainBuffer,pLen + 0x01);\r
+                                       }\r
+                                       else {\r
+                                               err("End flag missing!!!");\r
+                                               return 0;\r
+                                       }\r
+                               }\r
+                               else if(currentFlen > alen) {//the frame is incomplete.Yet to receive the full frame\r
+                                       MuxObjPtr->isWaiting = 1;\r
+                                       dbg("MEMCPY :alen= %d", alen);\r
+                                       memcpy(muxMainBuffer, muxTempBuffer + count, alen);\r
+                                       dbg("MEMCPY :DONE");\r
+                                       MuxObjPtr->pMsgLen =  currentFlen - alen;\r
+                                       MuxObjPtr->curMBufLen = alen ;\r
+                               }\r
+                       }\r
+                       else {\r
+                               err("Start flag missing!!!");\r
+                       }\r
+               }\r
+       } \r
+       else    {\r
+               err("Incorrect Length!!! or NULL Data!!");\r
+       }\r
+\r
+       dbg("Exit");\r
+       return 1;\r
+}\r
+\r
+#if 1\r
+void tcore_cmux_channel_init(CMUX_Channels channel_id)\r
+{\r
+       CHANNEL *ch = NULL;\r
+       dbg("Entry");\r
+       \r
+       ch = MuxObjPtr->channelInfo[channel_id];\r
+       memset(ch, 0x0, sizeof(CHANNEL));\r
+       \r
+       ch->ChannelId = channel_id;\r
+       ch->state = MUX_CHANNEL_SABM_SEND_WAITING_FOR_UA;\r
+\r
+       ch->co = NULL;\r
+       ch->hal = NULL;\r
+\r
+       /* TODO - Check if required */\r
+       ch->FrameType = SABM;\r
+       ch->ExtBit = 0x01;\r
+       ch->CRBit = 0x01;\r
+       ch->pollFinalBit = 0x01;\r
+\r
+       dbg("Channel ID %d initialized", channel_id);\r
+       \r
+       dbg("Exit");\r
+       return;\r
+}\r
+#else\r
+/*********************************************************\r
+\r
+OPEN CMUX CHANNEL\r
+*********************************************************/\r
+int open_cmux_channel(int channelID)\r
+{\r
+       CHANNEL *ch;\r
+       unsigned char *send_data;\r
+       int ret;\r
+       int len;\r
+       dbg("Entry");\r
+\r
+       ch = MuxObjPtr->channelInfo[channelID];\r
+\r
+       if(ch->state == MUX_CHANNEL_CLOSED) {\r
+               ch->FrameType = SABM;\r
+               ch->ExtBit = 0x01;\r
+               ch->CRBit = 0x01;\r
+\r
+               send_data = tcore_encode_cmux_frame(NULL, 0, channelID,  SABM, 0x01, 0x01, 0x01, &len); \r
+               \r
+               /* Directly send to Physical HAL */\r
+               ret = tcore_hal_send_data(MuxObjPtr->phy_hal,len, send_data);\r
+       }\r
+       else {\r
+               //channel is already initialized\r
+               err("Channel is already initialized");\r
+       }\r
+\r
+       dbg("Exit");\r
+       return 1;\r
+ }\r
+#endif\r
+\r
+/*********************************************************\r
+                       CLOSE CMUX CHANNEL\r
+*********************************************************/\r
+int tcore_cmux_close_channel(int channelID)\r
+{\r
+       CHANNEL *ch = NULL;\r
+       unsigned char *send_data = NULL;\r
+       int ret, len;\r
+       dbg("Entry");\r
+\r
+       ch = MuxObjPtr->channelInfo[channelID];\r
+       \r
+       if(ch->state != MUX_CHANNEL_CLOSED) {\r
+               ch->FrameType = DISC;\r
+               ch->ExtBit = 0x01;\r
+               ch->CRBit = 0x01;\r
+               ch->state = MUX_CHANNEL_DISC_SEND_WAITING_FOR_UA;\r
+\r
+               /* Send DSC command */\r
+               send_data = tcore_encode_cmux_frame(NULL,0, channelID,  DISC, 0x01, 0x01, 0x01, &len); \r
+               \r
+               /* Directly send to Physical HAL */\r
+               ret = tcore_hal_send_data(MuxObjPtr->phy_hal, len, send_data);\r
+\r
+       }\r
+       else {\r
+               /* Channel is already closed */\r
+               err("Channel is already closed");\r
+       }\r
+\r
+       dbg("Exit");\r
+       return 1;\r
+}\r
+\r
+static void tcore_cmux_free()\r
+{\r
+       int channel;\r
+       dbg("Entry");\r
+       \r
+       if(MuxObjPtr) {\r
+\r
+               /* Free Information Field */\r
+               if (MuxObjPtr->InfoField) \r
+                       free(MuxObjPtr->InfoField);\r
+                               \r
+               for (channel = 0 ; channel < MAX_CHANNEL_SUPPORTED ; channel++)\r
+               {\r
+                       /* Free Channel Information */\r
+                       if(MuxObjPtr->channelInfo[channel]) {\r
+                               free(MuxObjPtr->channelInfo[channel]);\r
+                       }\r
+               }\r
+\r
+               /* Free MUX Object */\r
+               free(MuxObjPtr);\r
+       }\r
+       else {\r
+               err("MUX Object doesn't exist");\r
+       }\r
+\r
+       dbg("Exit");\r
+       return;\r
+}\r
+\r
+void tcore_cmux_init(TcorePlugin *plugin, TcoreHal *h)\r
+{\r
+       TcoreHal *physical_hal = NULL;\r
+       unsigned char *data = NULL;\r
+       int data_len = 0;\r
+\r
+       int index;\r
+       dbg("Entry");\r
+\r
+       physical_hal = (TcoreHal *)h;\r
+       dbg("Physical HAL: %x", physical_hal);\r
+\r
+       /* Creat new CMUX Object */\r
+       MuxObjPtr = tcore_cmux_new();\r
+       if(NULL == MuxObjPtr) {\r
+               err("Failed to create MUX object");\r
+               return;\r
+       }\r
+\r
+       /* Save Plugin */\r
+       MuxObjPtr->p = plugin;\r
+       \r
+       /* Save Physical HAL */\r
+       MuxObjPtr->phy_hal = physical_hal;\r
+\r
+       /* Setting Receive callback function for data received from Physical HAL */\r
+       MuxObjPtr->cb_func= tcore_cmux_recv_mux_data;\r
+       \r
+      /* After MUX setup, AT parse functionality of PHY HAL should be disabled,\r
+        * here we change the mode of PHYSICAL HAL to Custom.\r
+        */\r
+       tcore_hal_set_mode(MuxObjPtr->phy_hal , TCORE_HAL_MODE_TRANSPARENT);\r
+       dbg("Physical HAL mode changed to Transparent");\r
\r
+       /* Initialize all the Channels */\r
+       /* Open all Channels */\r
+       for(index = 0 ; index < MAX_CHANNEL_SUPPORTED ; index++) {\r
+\r
+               dbg("Initialize the Channel %d", index); \r
+               tcore_cmux_channel_init((CMUX_Channels)index);\r
+               \r
+               dbg("Opening Channel %d", index);\r
+               /* Encode CMUX Frame */\r
+               data = tcore_encode_cmux_frame(NULL, 0, index, SABM, 0x01, 0x01, 0x01, &data_len);\r
+               if(NULL == data) {\r
+                       err("Failed to encode");\r
+                       return;\r
+               }\r
+               dbg("data_len: %d data: %s", data_len, data);\r
+\r
+#if 1\r
+               /* For Testing */\r
+               {\r
+                       int i;\r
+                       \r
+                       for(i = 0; i < data_len ; i++) {\r
+                               msg("%02x", data[i]);\r
+                       }\r
+               }\r
+#endif\r
+               /* Send Frame to CP */\r
+               tcore_hal_send_data(physical_hal, data_len, data);\r
+               dbg("CMUX Control Request sent to CP");\r
+\r
+               /* Set Core object and HAL */\r
+               tcore_cmux_link_core_object_hal((CMUX_Channels)index, plugin);\r
+       }\r
+\r
+       dbg("Exit");\r
+       return;\r
+}\r
+\r
+/*********************************************************\r
+\r
+MUX Close down\r
+\r
+*********************************************************/\r
+void tcore_cmux_close()\r
+{\r
+       int channel = 0;\r
+       int index = 0;\r
+       CoreObject *co = NULL;\r
+       GSList *co_list = NULL;\r
+       dbg("Entry");\r
+\r
+       for (channel = 0; channel < MAX_CHANNEL_SUPPORTED ; channel++) {\r
+               dbg("Channel ID: %d", channel);\r
+               index = 0;\r
+\r
+               /* Close Channel - Send DSC command */\r
+               tcore_cmux_close_channel(channel);\r
+\r
+               /* Revert Physical HAL as HAL of each Core Object associated to this Channel */\r
+               while (NULL != cmux_channel_Cobject[channel].Cobject_name[index]) {\r
+                       co = NULL;\r
+\r
+                       /* Core Objects list */\r
+                       co_list = MuxObjPtr->channelInfo[channel]->co;\r
+                       dbg("Core Objects list : %p", co_list);\r
+                       \r
+                       /* Core Object list may contain multiple Core Objects.\r
+                         * Revert to Physical HAL for each of the Core Objects associated\r
+                         * with this Channel\r
+                         */\r
+                       while(NULL != co_list) {\r
+                               if(NULL != co_list->data) {\r
+                                       if(!strcmp((const char *)cmux_channel_Cobject[channel].Cobject_name[index], (const char *)tcore_object_ref_name((CoreObject *)co_list->data))) {\r
+                                               co = (CoreObject *)co_list->data;\r
+                                               dbg("Found the Core Object");\r
+                                               break;\r
+                                       }\r
+                               }\r
+\r
+                               /* To next Core Object in the list */\r
+                               co_list = co_list->next;\r
+                       }\r
+\r
+                       /* Set the previous Physical HAL as HAL for Core Object */\r
+                       if(NULL != co) {\r
+                               tcore_object_set_hal(co, MuxObjPtr->phy_hal);\r
+                       }\r
+                       else {\r
+                               /* Proceed to next Channel */\r
+                               err("No more Core Objects present in this Channel");\r
+                               break;\r
+                       }\r
+\r
+                       /* To next Core Object */\r
+                       index++;\r
+               }\r
+               \r
+               /* Free Logical HAL for Channel */\r
+               tcore_hal_free(MuxObjPtr->channelInfo[channel]->hal);\r
+       }\r
+       \r
+       /* Change the mode of PHYSICAL HAL to Custom */\r
+       tcore_hal_set_mode(MuxObjPtr->phy_hal, TCORE_HAL_MODE_CUSTOM);\r
+\r
+       /* Free all the allocated memory */\r
+       tcore_cmux_free();\r
+               \r
+       dbg("Exit");\r
+       return;\r
+}\r