51 Called by CBulkOnlyTransport to create an instance of CControlInterface |
48 Called by CBulkOnlyTransport to create an instance of CControlInterface |
52 |
49 |
53 @param aParent reference to the CBulkOnlyTransport |
50 @param aParent reference to the CBulkOnlyTransport |
54 */ |
51 */ |
55 CBotControlInterface* CBotControlInterface::NewL(CBulkOnlyTransport& aParent) |
52 CBotControlInterface* CBotControlInterface::NewL(CBulkOnlyTransport& aParent) |
56 { |
53 { |
57 __MSFNSLOG |
54 CBotControlInterface* self = new(ELeave) CBotControlInterface(aParent); |
58 CBotControlInterface* self = new(ELeave) CBotControlInterface(aParent); |
55 CleanupStack::PushL(self); |
59 CleanupStack::PushL(self); |
56 self->ConstructL(); |
60 self->ConstructL(); |
57 CActiveScheduler::Add(self); |
61 CActiveScheduler::Add(self); |
58 CleanupStack::Pop(); |
62 CleanupStack::Pop(); |
59 return self; |
63 return self; |
60 } |
64 } |
|
65 |
61 |
66 |
62 |
67 void CBotControlInterface::ConstructL() |
63 void CBotControlInterface::ConstructL() |
68 { |
64 { |
69 __MSFNLOG |
65 } |
70 } |
|
71 |
66 |
72 |
67 |
73 /** |
68 /** |
74 c'tor |
69 c'tor |
75 |
70 |
76 @param aParent reference to the CBulkOnlyTransport |
71 @param aParent reference to the CBulkOnlyTransport |
77 */ |
72 */ |
78 CBotControlInterface::CBotControlInterface(CBulkOnlyTransport& aParent): |
73 CBotControlInterface::CBotControlInterface(CBulkOnlyTransport& aParent): |
79 CActive(EPriorityStandard), |
74 CActive(EPriorityStandard), |
80 iParent(aParent), |
75 iParent(aParent), |
81 iCurrentState(ENone) |
76 iCurrentState(ENone) |
82 { |
77 { |
83 __MSFNLOG |
78 } |
84 } |
|
85 |
79 |
86 |
80 |
87 /** |
81 /** |
88 d'tor |
82 d'tor |
89 */ |
83 */ |
90 CBotControlInterface::~CBotControlInterface() |
84 CBotControlInterface::~CBotControlInterface() |
91 { |
85 { |
92 __MSFNLOG |
86 Cancel(); |
93 Cancel(); |
87 } |
94 } |
|
95 |
88 |
96 |
89 |
97 /** |
90 /** |
98 Called by CBulkOnlyTransportStart to start control interface |
91 Called by CBulkOnlyTransportStart to start control interface |
99 */ |
92 */ |
100 TInt CBotControlInterface::Start() |
93 TInt CBotControlInterface::Start() |
101 { |
94 { |
102 __MSFNLOG |
|
103 if (IsActive()) |
95 if (IsActive()) |
104 { |
96 { |
105 __PRINT(_L("Still active\n")); |
97 __PRINT(_L("Still active\n")); |
106 return KErrServerBusy; |
98 return KErrServerBusy; |
107 } |
99 } |
108 ReadEp0Data(); |
100 ReadEp0Data(); |
109 return KErrNone; |
101 return KErrNone; |
110 } |
102 } |
111 |
103 |
112 |
104 |
113 /** |
105 /** |
114 Called by CBulkOnlyTransportStart to stop control interface |
106 Called by CBulkOnlyTransportStart to stop control interface |
115 */ |
107 */ |
116 void CBotControlInterface::Stop() |
108 void CBotControlInterface::Stop() |
117 { |
109 { |
118 __MSFNLOG |
110 if (!IsActive()) |
119 if (!IsActive()) |
111 { |
120 { |
112 __PRINT(_L("Not active\n")); |
121 __PRINT(_L("Not active\n")); |
113 return; |
122 return; |
114 } |
123 } |
115 |
124 |
116 __PRINT(_L("\nStopping...\n")); |
125 __PRINT(_L("\nStopping...\n")); |
117 iCurrentState = ENone; |
126 iCurrentState = ENone; |
118 Cancel(); |
127 Cancel(); |
119 } |
128 } |
|
129 |
120 |
130 |
121 |
131 /** |
122 /** |
132 Cancel outstanding request (if any) |
123 Cancel outstanding request (if any) |
133 */ |
124 */ |
134 void CBotControlInterface::DoCancel() |
125 void CBotControlInterface::DoCancel() |
135 { |
126 { |
136 __MSFNLOG |
127 switch(iCurrentState) |
137 switch(iCurrentState) |
128 { |
138 { |
129 case EReadEp0Data: |
139 case EReadEp0Data: |
130 iParent.Ldd().ReadCancel(EEndpoint0); |
140 iParent.Ldd().ReadCancel(EEndpoint0); |
131 break; |
141 break; |
132 case ESendMaxLun: |
142 case ESendMaxLun: |
133 iParent.Ldd().WriteCancel(EEndpoint0); |
143 iParent.Ldd().WriteCancel(EEndpoint0); |
134 break; |
144 break; |
135 default: |
145 default: |
136 __PRINT(_L("\nWrong state !\n")); |
146 __PRINT(_L("\nWrong state !\n")); |
137 __ASSERT_DEBUG(EFalse, User::Panic(KUsbMsClientPanicCat, EMsControlInterfaceBadState)); |
147 __ASSERT_DEBUG(EFalse, User::Panic(KUsbMsClientPanicCat, EMsControlInterfaceBadState)); |
138 } |
148 } |
139 } |
149 } |
|
150 |
140 |
151 |
141 |
152 /** |
142 /** |
153 Implement CBotControlInterface state machine |
143 Implement CBotControlInterface state machine |
154 */ |
144 */ |
155 void CBotControlInterface::RunL() |
145 void CBotControlInterface::RunL() |
156 { |
146 { |
157 __MSFNLOG |
147 if (iStatus != KErrNone) |
158 if (iStatus != KErrNone) |
148 { |
159 { |
149 __PRINT1(_L("Error %d in RunL\n"), iStatus.Int()); |
160 __PRINT1(_L("Error %d in RunL\n"), iStatus.Int()); |
150 |
161 |
151 //read EP0 again |
162 //read EP0 again |
152 ReadEp0Data(); |
163 ReadEp0Data(); |
153 return; |
164 return; |
154 } |
165 } |
155 |
166 |
156 switch (iCurrentState) |
167 switch (iCurrentState) |
157 { |
168 { |
158 case ESendMaxLun: |
169 case ESendMaxLun: |
159 ReadEp0Data(); |
170 ReadEp0Data(); |
160 break; |
171 break; |
161 |
172 |
162 case EReadEp0Data: |
173 case EReadEp0Data: |
163 DecodeEp0Data(); |
174 DecodeEp0Data(); |
164 break; |
175 break; |
165 |
176 |
166 default: |
177 default: |
167 __PRINT(_L(" error: (Shouldn't end up here...)\n")); |
178 __PRINT(_L(" error: (Shouldn't end up here...)\n")); |
168 __ASSERT_DEBUG(EFalse, User::Panic(KUsbMsClientPanicCat, EMsControlInterfaceBadState)); |
179 __ASSERT_DEBUG(EFalse, User::Panic(KUsbMsClientPanicCat, EMsControlInterfaceBadState)); |
169 break; |
180 break; |
170 } |
181 } |
171 } |
182 } |
|
183 |
172 |
184 |
173 |
185 /** |
174 /** |
186 Post a read request to EEndpoint0 to read request header |
175 Post a read request to EEndpoint0 to read request header |
187 */ |
176 */ |
188 void CBotControlInterface::ReadEp0Data() |
177 void CBotControlInterface::ReadEp0Data() |
189 { |
178 { |
190 __MSFNLOG |
179 iParent.Ldd().Read(iStatus, EEndpoint0, iData, KRequestHdrSize); |
191 iParent.Ldd().Read(iStatus, EEndpoint0, iData, KRequestHdrSize); |
180 iCurrentState = EReadEp0Data; |
192 iCurrentState = EReadEp0Data; |
181 SetActive(); |
193 SetActive(); |
182 } |
194 } |
|
195 |
183 |
196 |
184 |
197 /** |
185 /** |
198 Decode request header and do appropriate action - get max LUN info or post a reset request |
186 Decode request header and do appropriate action - get max LUN info or post a reset request |
199 */ |
187 */ |
200 void CBotControlInterface::DecodeEp0Data() |
188 void CBotControlInterface::DecodeEp0Data() |
201 { |
189 { |
202 __MSFNLOG |
190 TInt err = iRequestHeader.Decode(iData); |
203 TInt err = iRequestHeader.Decode(iData); |
191 if (err != KErrNone) |
204 if (err != KErrNone) |
192 return; |
205 return; |
|
206 |
193 |
207 switch(iRequestHeader.iRequest) |
194 switch(iRequestHeader.iRequest) |
208 { |
195 { |
209 // |
196 // |
210 // GET MAX LUN (0xFE) |
197 // GET MAX LUN (0xFE) |
211 // |
198 // |
212 case TBotFunctionReqCb::EReqGetMaxLun: |
199 case TBotFunctionReqCb::EReqGetMaxLun: |
213 { |
200 { |
214 __PRINT1(_L("DecodeEp0Data : 'Get Max LUN' Request MaxLun = %d"),iParent.MaxLun()); |
201 __PRINT1(_L("DecodeEp0Data : 'Get Max LUN' Request MaxLun = %d"),iParent.MaxLun()); |
215 |
202 |
216 if ( iRequestHeader.iRequestType != 0xA1 //value from USB MS BOT spec |
203 if ( iRequestHeader.iRequestType != 0xA1 //value from USB MS BOT spec |
217 || iRequestHeader.iIndex > 15 |
204 || iRequestHeader.iIndex > 15 |
218 || iRequestHeader.iValue != 0 |
205 || iRequestHeader.iValue != 0 |
219 || iRequestHeader.iLength != 1) |
206 || iRequestHeader.iLength != 1) |
220 { |
207 { |
221 __PRINT(_L("GetMaxLun command packet check error")); |
208 __PRINT(_L("GetMaxLun command packet check error")); |
222 iParent.Ldd().EndpointZeroRequestError(); |
209 iParent.Ldd().EndpointZeroRequestError(); |
223 ReadEp0Data(); //try to get another request |
210 ReadEp0Data(); //try to get another request |
224 } |
211 } |
225 else |
212 else |
226 { |
213 { |
227 iData.FillZ(1); //Return only 1 byte to host |
214 iData.FillZ(1); //Return only 1 byte to host |
228 iData[0] = static_cast<TUint8>(iParent.MaxLun()); // Supported Units |
215 iData[0] = static_cast<TUint8>(iParent.MaxLun()); // Supported Units |
229 iParent.Ldd().Write(iStatus, EEndpoint0, iData, 1); |
216 iParent.Ldd().Write(iStatus, EEndpoint0, iData, 1); |
230 |
217 |
231 iCurrentState = ESendMaxLun; |
218 iCurrentState = ESendMaxLun; |
232 SetActive(); |
219 SetActive(); |
233 } |
220 } |
234 } |
221 } |
235 break; |
222 break; |
236 // |
223 // |
237 // RESET (0xFF) |
224 // RESET (0xFF) |
238 // |
225 // |
239 case TBotFunctionReqCb::EReqReset: |
226 case TBotFunctionReqCb::EReqReset: |
240 { |
227 { |
241 __PRINT(_L("DecodeEp0Data : 'Mass Storage Reset' Request")); |
228 __PRINT(_L("DecodeEp0Data : 'Mass Storage Reset' Request")); |
242 __TESTMODEPRINT("------- BOT RESET ------"); |
229 __TESTMODEPRINT("------- BOT RESET ------"); |
243 |
230 |
244 if ( iRequestHeader.iRequestType != 0x21 //value from USB MS BOT spec |
231 if ( iRequestHeader.iRequestType != 0x21 //value from USB MS BOT spec |
245 || iRequestHeader.iIndex > 15 |
232 || iRequestHeader.iIndex > 15 |
246 || iRequestHeader.iValue != 0 |
233 || iRequestHeader.iValue != 0 |
247 || iRequestHeader.iLength != 0) |
234 || iRequestHeader.iLength != 0) |
248 { |
235 { |
249 __PRINT(_L("MSC Reset command packet check error")); |
236 __PRINT(_L("MSC Reset command packet check error")); |
250 iParent.Ldd().EndpointZeroRequestError(); |
237 iParent.Ldd().EndpointZeroRequestError(); |
251 ReadEp0Data(); //try to get another request |
238 ReadEp0Data(); //try to get another request |
252 } |
239 } |
253 else |
240 else |
254 { |
241 { |
255 iParent.HwStop(); |
242 iParent.HwStop(); |
256 iParent.Controller().Reset(); |
243 iParent.Controller().Reset(); |
257 iParent.HwStart(ETrue); |
244 iParent.HwStart(ETrue); |
258 iParent.Ldd().SendEp0StatusPacket(); |
245 iParent.Ldd().SendEp0StatusPacket(); |
259 } |
246 } |
260 } |
247 } |
261 break; |
248 break; |
262 // |
249 // |
263 // Unknown? |
250 // Unknown? |
264 // |
251 // |
265 default: |
252 default: |
266 __PRINT(_L("DecodeEp0Data : Unknown Request")); |
253 __PRINT(_L("DecodeEp0Data : Unknown Request")); |
267 ReadEp0Data(); //try to get another request |
254 ReadEp0Data(); //try to get another request |
268 break; |
255 break; |
269 } |
256 } |
270 } |
257 } |