Commit | Line | Data |
---|---|---|
635d2b00 GKH |
1 | /** @file router_transport.c |
2 | * | |
3 | * | |
4 | * Copyright (C) Cambridge Silicon Radio Ltd 2006-2010. All rights reserved. | |
5 | * | |
6 | * Refer to LICENSE.txt included with this source code for details on | |
7 | * the license terms. | |
8 | * | |
9 | ****************************************************************************/ | |
10 | ||
11 | #include "unifi_priv.h" | |
12 | ||
13 | #include "csr_types.h" | |
14 | #include "csr_sched.h" | |
15 | #include "csr_msgconv.h" | |
16 | ||
17 | #include "sme_userspace.h" | |
18 | ||
19 | #include "csr_wifi_hostio_prim.h" | |
20 | #include "csr_wifi_router_lib.h" | |
21 | #include "csr_wifi_router_sef.h" | |
22 | #include "csr_wifi_router_converter_init.h" | |
23 | #include "csr_wifi_router_ctrl_lib.h" | |
24 | #include "csr_wifi_router_ctrl_sef.h" | |
25 | #include "csr_wifi_router_ctrl_converter_init.h" | |
26 | #include "csr_wifi_sme_prim.h" | |
27 | #include "csr_wifi_sme_sef.h" | |
28 | #include "csr_wifi_sme_converter_init.h" | |
29 | #ifdef CSR_SUPPORT_WEXT | |
30 | #ifdef CSR_SUPPORT_WEXT_AP | |
31 | #include "csr_wifi_nme_ap_prim.h" | |
32 | #include "csr_wifi_nme_ap_sef.h" | |
33 | #include "csr_wifi_nme_ap_converter_init.h" | |
34 | #endif | |
35 | #endif | |
36 | ||
37 | static unifi_priv_t *drvpriv = NULL; | |
38 | void CsrWifiRouterTransportInit(unifi_priv_t *priv) | |
39 | { | |
40 | unifi_trace(priv, UDBG1, "CsrWifiRouterTransportInit: \n"); | |
41 | ||
42 | drvpriv = priv; | |
43 | (void)CsrMsgConvInit(); | |
44 | CsrWifiRouterConverterInit(); | |
45 | CsrWifiRouterCtrlConverterInit(); | |
46 | CsrWifiSmeConverterInit(); | |
47 | #ifdef CSR_SUPPORT_WEXT | |
48 | #ifdef CSR_SUPPORT_WEXT_AP | |
49 | CsrWifiNmeApConverterInit(); | |
50 | #endif | |
51 | #endif | |
52 | } | |
53 | ||
54 | void CsrWifiRouterTransportDeinit(unifi_priv_t *priv) | |
55 | { | |
56 | unifi_trace(priv, UDBG1, "CsrWifiRouterTransportDeinit: \n"); | |
57 | if (priv == drvpriv) | |
58 | { | |
59 | CsrMsgConvDeinit(); | |
60 | drvpriv = NULL; | |
61 | } | |
62 | } | |
63 | ||
64 | void CsrWifiRouterTransportRecv(unifi_priv_t *priv, CsrUint8* buffer, CsrSize bufferLength) | |
65 | { | |
66 | CsrMsgConvMsgEntry* msgEntry; | |
67 | CsrUint16 primType; | |
68 | CsrSchedQid src; | |
69 | CsrSchedQid dest; | |
70 | CsrUint16 msgType; | |
71 | CsrSize offset = 0; | |
72 | CsrWifiFsmEvent* msg; | |
73 | ||
74 | /* Decode the prim and message type */ | |
75 | CsrUint16Des(&primType, buffer, &offset); | |
76 | CsrUint16Des(&src, buffer, &offset); | |
77 | CsrUint16Des(&dest, buffer, &offset); | |
78 | CsrUint16Des(&msgType, buffer, &offset); | |
79 | offset -= 2; /* Adjust as the Deserialise Function will read this as well */ | |
80 | ||
81 | unifi_trace(priv, UDBG4, "CsrWifiRouterTransportRecv: primType=0x%.4X, msgType=0x%.4X, bufferLength=%d\n", | |
82 | primType, msgType, bufferLength); | |
83 | ||
84 | /* Special handling for HOSTIO messages.... */ | |
85 | if (primType == CSR_WIFI_HOSTIO_PRIM) | |
86 | { | |
87 | CsrWifiRouterCtrlHipReq req = {{CSR_WIFI_ROUTER_CTRL_HIP_REQ, CSR_WIFI_ROUTER_CTRL_PRIM, dest, src, NULL}, 0, NULL, 0, NULL, 0, NULL}; | |
88 | ||
89 | req.mlmeCommandLength = bufferLength; | |
90 | req.mlmeCommand = buffer; | |
91 | ||
92 | offset += 8;/* Skip the id, src, dest and slot number */ | |
93 | CsrUint16Des(&req.dataRef1Length, buffer, &offset); | |
94 | offset += 2; /* Skip the slot number */ | |
95 | CsrUint16Des(&req.dataRef2Length, buffer, &offset); | |
96 | ||
97 | if (req.dataRef1Length) | |
98 | { | |
99 | CsrUint16 dr1Offset = (bufferLength - req.dataRef2Length) - req.dataRef1Length; | |
100 | req.dataRef1 = &buffer[dr1Offset]; | |
101 | } | |
102 | ||
103 | if (req.dataRef2Length) | |
104 | { | |
105 | CsrUint16 dr2Offset = bufferLength - req.dataRef2Length; | |
106 | req.dataRef2 = &buffer[dr2Offset]; | |
107 | } | |
108 | ||
109 | /* Copy the hip data but strip off the prim type */ | |
110 | req.mlmeCommandLength -= (req.dataRef1Length + req.dataRef2Length + 6); | |
111 | req.mlmeCommand = &buffer[6]; | |
112 | ||
113 | CsrWifiRouterCtrlHipReqHandler(priv, &req.common); | |
114 | return; | |
115 | } | |
116 | ||
117 | msgEntry = CsrMsgConvFindEntry(primType, msgType); | |
118 | if (!msgEntry) | |
119 | { | |
120 | unifi_error(priv, "CsrWifiRouterTransportDeserialiseAndSend can not process the message. primType=0x%.4X, msgType=0x%.4X\n", | |
121 | primType, msgType); | |
122 | dump(buffer, bufferLength); | |
123 | return; | |
124 | } | |
125 | ||
126 | msg = (CsrWifiFsmEvent*)(msgEntry->deserFunc)(&buffer[offset], bufferLength - offset); | |
127 | ||
128 | msg->primtype = primType; | |
129 | msg->type = msgType; | |
130 | msg->source = src; | |
131 | msg->destination = dest; | |
132 | ||
133 | switch(primType) | |
134 | { | |
135 | case CSR_WIFI_ROUTER_CTRL_PRIM: | |
136 | CsrWifiRouterCtrlDownstreamStateHandlers[msg->type - CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST](priv, msg); | |
137 | CsrWifiRouterCtrlFreeDownstreamMessageContents(CSR_WIFI_ROUTER_CTRL_PRIM, msg); | |
138 | break; | |
139 | case CSR_WIFI_ROUTER_PRIM: | |
140 | CsrWifiRouterDownstreamStateHandlers[msg->type - CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_LOWEST](priv, msg); | |
141 | CsrWifiRouterFreeDownstreamMessageContents(CSR_WIFI_ROUTER_PRIM, msg); | |
142 | break; | |
143 | case CSR_WIFI_SME_PRIM: | |
144 | CsrWifiSmeUpstreamStateHandlers[msg->type - CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST](priv, msg); | |
145 | CsrWifiSmeFreeUpstreamMessageContents(CSR_WIFI_SME_PRIM, msg); | |
146 | break; | |
147 | #ifdef CSR_SUPPORT_WEXT | |
148 | #ifdef CSR_SUPPORT_WEXT_AP | |
149 | case CSR_WIFI_NME_AP_PRIM: | |
150 | CsrWifiNmeApUpstreamStateHandlers(priv, msg); | |
151 | CsrWifiNmeApFreeUpstreamMessageContents(CSR_WIFI_NME_AP_PRIM, msg); | |
152 | break; | |
153 | #endif | |
154 | #endif | |
155 | default: | |
156 | unifi_error(priv, "CsrWifiRouterTransportDeserialiseAndSend unhandled prim type 0x%.4X\n", primType); | |
157 | break; | |
158 | } | |
159 | CsrPmemFree(msg); | |
160 | } | |
161 | ||
162 | static void CsrWifiRouterTransportSerialiseAndSend(CsrUint16 primType, void* msg) | |
163 | { | |
164 | CsrWifiFsmEvent* evt = (CsrWifiFsmEvent*)msg; | |
165 | CsrMsgConvMsgEntry* msgEntry; | |
166 | CsrSize msgSize; | |
167 | CsrSize encodeBufferLen = 0; | |
168 | CsrSize offset = 0; | |
169 | CsrUint8* encodeBuffer; | |
170 | ||
171 | unifi_trace(drvpriv, UDBG4, "CsrWifiRouterTransportSerialiseAndSend: primType=0x%.4X, msgType=0x%.4X\n", | |
172 | primType, evt->type); | |
173 | ||
174 | msgEntry = CsrMsgConvFindEntry(primType, evt->type); | |
175 | if (!msgEntry) | |
176 | { | |
177 | unifi_error(drvpriv, "CsrWifiRouterTransportSerialiseAndSend can not process the message. primType=0x%.4X, msgType=0x%.4X\n", | |
178 | primType, evt->type); | |
179 | return; | |
180 | } | |
181 | ||
182 | msgSize = 6 + (msgEntry->sizeofFunc)((void*)msg); | |
183 | ||
184 | encodeBuffer = CsrPmemAlloc(msgSize); | |
185 | ||
186 | /* Encode PrimType */ | |
187 | CsrUint16Ser(encodeBuffer, &encodeBufferLen, primType); | |
188 | CsrUint16Ser(encodeBuffer, &encodeBufferLen, evt->source); | |
189 | CsrUint16Ser(encodeBuffer, &encodeBufferLen, evt->destination); | |
190 | ||
191 | (void)(msgEntry->serFunc)(&encodeBuffer[encodeBufferLen], &offset, msg); | |
192 | encodeBufferLen += offset; | |
193 | ||
194 | uf_sme_queue_message(drvpriv, encodeBuffer, encodeBufferLen); | |
195 | ||
196 | /* Do not use msgEntry->freeFunc because the memory is owned by the driver */ | |
197 | CsrPmemFree(msg); | |
198 | } | |
199 | ||
200 | #if defined(CSR_LOG_ENABLE) && defined(CSR_LOG_INCLUDE_FILE_NAME_AND_LINE_NUMBER) | |
201 | void CsrSchedMessagePutStringLog(CsrSchedQid q, CsrUint16 mi, void *mv, CsrUint32 line, CsrCharString *file) | |
202 | #else | |
203 | void CsrSchedMessagePut(CsrSchedQid q, CsrUint16 mi, void *mv) | |
204 | #endif | |
205 | { | |
206 | CsrWifiFsmEvent* evt = (CsrWifiFsmEvent*)mv; | |
207 | evt->destination = q; | |
208 | CsrWifiRouterTransportSerialiseAndSend(mi, mv); | |
209 | } | |
210 |