xref: /aosp_15_r20/system/chre/chpp/services/wwan.c (revision 84e339476a462649f82315436d70fd732297a399)
1*84e33947SAndroid Build Coastguard Worker /*
2*84e33947SAndroid Build Coastguard Worker  * Copyright (C) 2020 The Android Open Source Project
3*84e33947SAndroid Build Coastguard Worker  *
4*84e33947SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*84e33947SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*84e33947SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*84e33947SAndroid Build Coastguard Worker  *
8*84e33947SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*84e33947SAndroid Build Coastguard Worker  *
10*84e33947SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*84e33947SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*84e33947SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*84e33947SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*84e33947SAndroid Build Coastguard Worker  * limitations under the License.
15*84e33947SAndroid Build Coastguard Worker  */
16*84e33947SAndroid Build Coastguard Worker 
17*84e33947SAndroid Build Coastguard Worker #include "chpp/services/wwan.h"
18*84e33947SAndroid Build Coastguard Worker 
19*84e33947SAndroid Build Coastguard Worker #include <inttypes.h>
20*84e33947SAndroid Build Coastguard Worker #include <stdbool.h>
21*84e33947SAndroid Build Coastguard Worker #include <stddef.h>
22*84e33947SAndroid Build Coastguard Worker #include <stdint.h>
23*84e33947SAndroid Build Coastguard Worker 
24*84e33947SAndroid Build Coastguard Worker #include "chpp/common/standard_uuids.h"
25*84e33947SAndroid Build Coastguard Worker #include "chpp/common/wwan.h"
26*84e33947SAndroid Build Coastguard Worker #include "chpp/common/wwan_types.h"
27*84e33947SAndroid Build Coastguard Worker #include "chpp/log.h"
28*84e33947SAndroid Build Coastguard Worker #include "chpp/macros.h"
29*84e33947SAndroid Build Coastguard Worker #include "chpp/memory.h"
30*84e33947SAndroid Build Coastguard Worker #include "chpp/services.h"
31*84e33947SAndroid Build Coastguard Worker #include "chre/pal/wwan.h"
32*84e33947SAndroid Build Coastguard Worker 
33*84e33947SAndroid Build Coastguard Worker /************************************************
34*84e33947SAndroid Build Coastguard Worker  *  Prototypes
35*84e33947SAndroid Build Coastguard Worker  ***********************************************/
36*84e33947SAndroid Build Coastguard Worker 
37*84e33947SAndroid Build Coastguard Worker static enum ChppAppErrorCode chppDispatchWwanRequest(void *serviceContext,
38*84e33947SAndroid Build Coastguard Worker                                                      uint8_t *buf, size_t len);
39*84e33947SAndroid Build Coastguard Worker static void chppWwanServiceNotifyReset(void *serviceContext);
40*84e33947SAndroid Build Coastguard Worker 
41*84e33947SAndroid Build Coastguard Worker /************************************************
42*84e33947SAndroid Build Coastguard Worker  *  Private Definitions
43*84e33947SAndroid Build Coastguard Worker  ***********************************************/
44*84e33947SAndroid Build Coastguard Worker 
45*84e33947SAndroid Build Coastguard Worker /**
46*84e33947SAndroid Build Coastguard Worker  * Configuration parameters for this service
47*84e33947SAndroid Build Coastguard Worker  */
48*84e33947SAndroid Build Coastguard Worker static const struct ChppService kWwanServiceConfig = {
49*84e33947SAndroid Build Coastguard Worker     .descriptor.uuid = CHPP_UUID_WWAN_STANDARD,
50*84e33947SAndroid Build Coastguard Worker 
51*84e33947SAndroid Build Coastguard Worker     // Human-readable name
52*84e33947SAndroid Build Coastguard Worker     .descriptor.name = "WWAN",
53*84e33947SAndroid Build Coastguard Worker 
54*84e33947SAndroid Build Coastguard Worker     // Version
55*84e33947SAndroid Build Coastguard Worker     .descriptor.version.major = 1,
56*84e33947SAndroid Build Coastguard Worker     .descriptor.version.minor = 0,
57*84e33947SAndroid Build Coastguard Worker     .descriptor.version.patch = 0,
58*84e33947SAndroid Build Coastguard Worker 
59*84e33947SAndroid Build Coastguard Worker     // Notifies service if CHPP is reset
60*84e33947SAndroid Build Coastguard Worker     .resetNotifierFunctionPtr = &chppWwanServiceNotifyReset,
61*84e33947SAndroid Build Coastguard Worker 
62*84e33947SAndroid Build Coastguard Worker     // Client request dispatch function pointer
63*84e33947SAndroid Build Coastguard Worker     .requestDispatchFunctionPtr = &chppDispatchWwanRequest,
64*84e33947SAndroid Build Coastguard Worker 
65*84e33947SAndroid Build Coastguard Worker     // Client notification dispatch function pointer
66*84e33947SAndroid Build Coastguard Worker     .notificationDispatchFunctionPtr = NULL,  // Not supported
67*84e33947SAndroid Build Coastguard Worker 
68*84e33947SAndroid Build Coastguard Worker     // Min length is the entire header
69*84e33947SAndroid Build Coastguard Worker     .minLength = sizeof(struct ChppAppHeader),
70*84e33947SAndroid Build Coastguard Worker };
71*84e33947SAndroid Build Coastguard Worker 
72*84e33947SAndroid Build Coastguard Worker /**
73*84e33947SAndroid Build Coastguard Worker  * Structure to maintain state for the WWAN service and its Request/Response
74*84e33947SAndroid Build Coastguard Worker  * (RR) functionality.
75*84e33947SAndroid Build Coastguard Worker  */
76*84e33947SAndroid Build Coastguard Worker struct ChppWwanServiceState {
77*84e33947SAndroid Build Coastguard Worker   struct ChppEndpointState service;  // CHPP service state
78*84e33947SAndroid Build Coastguard Worker   const struct chrePalWwanApi *api;  // WWAN PAL API
79*84e33947SAndroid Build Coastguard Worker 
80*84e33947SAndroid Build Coastguard Worker   struct ChppIncomingRequestState open;              // Service init state
81*84e33947SAndroid Build Coastguard Worker   struct ChppIncomingRequestState close;             // Service deinit state
82*84e33947SAndroid Build Coastguard Worker   struct ChppIncomingRequestState getCapabilities;   // Get Capabilities state
83*84e33947SAndroid Build Coastguard Worker   struct ChppIncomingRequestState getCellInfoAsync;  // Get CellInfo Async state
84*84e33947SAndroid Build Coastguard Worker };
85*84e33947SAndroid Build Coastguard Worker 
86*84e33947SAndroid Build Coastguard Worker // Note: This global definition of gWwanServiceContext supports only one
87*84e33947SAndroid Build Coastguard Worker // instance of the CHPP WWAN service at a time. This limitation is primarily due
88*84e33947SAndroid Build Coastguard Worker // to the PAL API.
89*84e33947SAndroid Build Coastguard Worker // It would be possible to generate different API and callback pointers to
90*84e33947SAndroid Build Coastguard Worker // support multiple instances of the service or modify the PAL API to pass a
91*84e33947SAndroid Build Coastguard Worker // void* for context, but this is not necessary in the current version of CHPP.
92*84e33947SAndroid Build Coastguard Worker // In such case, wwanServiceContext would be allocated dynamically as part of
93*84e33947SAndroid Build Coastguard Worker // chppRegisterWwanService(), e.g.
94*84e33947SAndroid Build Coastguard Worker //   struct ChppWwanServiceState *wwanServiceContext = chppMalloc(...);
95*84e33947SAndroid Build Coastguard Worker // instead of globally here.
96*84e33947SAndroid Build Coastguard Worker struct ChppWwanServiceState gWwanServiceContext;
97*84e33947SAndroid Build Coastguard Worker 
98*84e33947SAndroid Build Coastguard Worker /************************************************
99*84e33947SAndroid Build Coastguard Worker  *  Prototypes
100*84e33947SAndroid Build Coastguard Worker  ***********************************************/
101*84e33947SAndroid Build Coastguard Worker 
102*84e33947SAndroid Build Coastguard Worker static enum ChppAppErrorCode chppWwanServiceOpen(
103*84e33947SAndroid Build Coastguard Worker     struct ChppWwanServiceState *wwanServiceContext,
104*84e33947SAndroid Build Coastguard Worker     struct ChppAppHeader *requestHeader);
105*84e33947SAndroid Build Coastguard Worker static enum ChppAppErrorCode chppWwanServiceClose(
106*84e33947SAndroid Build Coastguard Worker     struct ChppWwanServiceState *wwanServiceContext,
107*84e33947SAndroid Build Coastguard Worker     struct ChppAppHeader *requestHeader);
108*84e33947SAndroid Build Coastguard Worker static enum ChppAppErrorCode chppWwanServiceGetCapabilities(
109*84e33947SAndroid Build Coastguard Worker     struct ChppWwanServiceState *wwanServiceContext,
110*84e33947SAndroid Build Coastguard Worker     struct ChppAppHeader *requestHeader);
111*84e33947SAndroid Build Coastguard Worker static enum ChppAppErrorCode chppWwanServiceGetCellInfoAsync(
112*84e33947SAndroid Build Coastguard Worker     struct ChppWwanServiceState *wwanServiceContext,
113*84e33947SAndroid Build Coastguard Worker     struct ChppAppHeader *requestHeader);
114*84e33947SAndroid Build Coastguard Worker 
115*84e33947SAndroid Build Coastguard Worker static void chppWwanServiceCellInfoResultCallback(
116*84e33947SAndroid Build Coastguard Worker     struct chreWwanCellInfoResult *result);
117*84e33947SAndroid Build Coastguard Worker 
118*84e33947SAndroid Build Coastguard Worker /************************************************
119*84e33947SAndroid Build Coastguard Worker  *  Private Functions
120*84e33947SAndroid Build Coastguard Worker  ***********************************************/
121*84e33947SAndroid Build Coastguard Worker 
122*84e33947SAndroid Build Coastguard Worker /**
123*84e33947SAndroid Build Coastguard Worker  * Dispatches a client request from the transport layer that is determined to be
124*84e33947SAndroid Build Coastguard Worker  * for the WWAN service. If the result of the dispatch is an error, this
125*84e33947SAndroid Build Coastguard Worker  * function responds to the client with the same error.
126*84e33947SAndroid Build Coastguard Worker  *
127*84e33947SAndroid Build Coastguard Worker  * This function is called from the app layer using its function pointer given
128*84e33947SAndroid Build Coastguard Worker  * during service registration.
129*84e33947SAndroid Build Coastguard Worker  *
130*84e33947SAndroid Build Coastguard Worker  * @param serviceContext Maintains status for each service instance.
131*84e33947SAndroid Build Coastguard Worker  * @param buf Input data. Cannot be null.
132*84e33947SAndroid Build Coastguard Worker  * @param len Length of input data in bytes.
133*84e33947SAndroid Build Coastguard Worker  *
134*84e33947SAndroid Build Coastguard Worker  * @return Indicates the result of this function call.
135*84e33947SAndroid Build Coastguard Worker  */
chppDispatchWwanRequest(void * serviceContext,uint8_t * buf,size_t len)136*84e33947SAndroid Build Coastguard Worker static enum ChppAppErrorCode chppDispatchWwanRequest(void *serviceContext,
137*84e33947SAndroid Build Coastguard Worker                                                      uint8_t *buf, size_t len) {
138*84e33947SAndroid Build Coastguard Worker   struct ChppAppHeader *rxHeader = (struct ChppAppHeader *)buf;
139*84e33947SAndroid Build Coastguard Worker   struct ChppWwanServiceState *wwanServiceContext =
140*84e33947SAndroid Build Coastguard Worker       (struct ChppWwanServiceState *)serviceContext;
141*84e33947SAndroid Build Coastguard Worker   struct ChppIncomingRequestState *inReqState = NULL;
142*84e33947SAndroid Build Coastguard Worker   enum ChppAppErrorCode error = CHPP_APP_ERROR_NONE;
143*84e33947SAndroid Build Coastguard Worker   bool dispatched = true;
144*84e33947SAndroid Build Coastguard Worker 
145*84e33947SAndroid Build Coastguard Worker   UNUSED_VAR(len);
146*84e33947SAndroid Build Coastguard Worker 
147*84e33947SAndroid Build Coastguard Worker   switch (rxHeader->command) {
148*84e33947SAndroid Build Coastguard Worker     case CHPP_WWAN_OPEN: {
149*84e33947SAndroid Build Coastguard Worker       inReqState = &wwanServiceContext->open;
150*84e33947SAndroid Build Coastguard Worker       chppTimestampIncomingRequest(inReqState, rxHeader);
151*84e33947SAndroid Build Coastguard Worker       error = chppWwanServiceOpen(wwanServiceContext, rxHeader);
152*84e33947SAndroid Build Coastguard Worker       break;
153*84e33947SAndroid Build Coastguard Worker     }
154*84e33947SAndroid Build Coastguard Worker 
155*84e33947SAndroid Build Coastguard Worker     case CHPP_WWAN_CLOSE: {
156*84e33947SAndroid Build Coastguard Worker       inReqState = &wwanServiceContext->close;
157*84e33947SAndroid Build Coastguard Worker       chppTimestampIncomingRequest(inReqState, rxHeader);
158*84e33947SAndroid Build Coastguard Worker       error = chppWwanServiceClose(wwanServiceContext, rxHeader);
159*84e33947SAndroid Build Coastguard Worker       break;
160*84e33947SAndroid Build Coastguard Worker     }
161*84e33947SAndroid Build Coastguard Worker 
162*84e33947SAndroid Build Coastguard Worker     case CHPP_WWAN_GET_CAPABILITIES: {
163*84e33947SAndroid Build Coastguard Worker       inReqState = &wwanServiceContext->getCapabilities;
164*84e33947SAndroid Build Coastguard Worker       chppTimestampIncomingRequest(inReqState, rxHeader);
165*84e33947SAndroid Build Coastguard Worker       error = chppWwanServiceGetCapabilities(wwanServiceContext, rxHeader);
166*84e33947SAndroid Build Coastguard Worker       break;
167*84e33947SAndroid Build Coastguard Worker     }
168*84e33947SAndroid Build Coastguard Worker 
169*84e33947SAndroid Build Coastguard Worker     case CHPP_WWAN_GET_CELLINFO_ASYNC: {
170*84e33947SAndroid Build Coastguard Worker       inReqState = &wwanServiceContext->getCellInfoAsync;
171*84e33947SAndroid Build Coastguard Worker       chppTimestampIncomingRequest(inReqState, rxHeader);
172*84e33947SAndroid Build Coastguard Worker       error = chppWwanServiceGetCellInfoAsync(wwanServiceContext, rxHeader);
173*84e33947SAndroid Build Coastguard Worker       break;
174*84e33947SAndroid Build Coastguard Worker     }
175*84e33947SAndroid Build Coastguard Worker 
176*84e33947SAndroid Build Coastguard Worker     default: {
177*84e33947SAndroid Build Coastguard Worker       dispatched = false;
178*84e33947SAndroid Build Coastguard Worker       error = CHPP_APP_ERROR_INVALID_COMMAND;
179*84e33947SAndroid Build Coastguard Worker       break;
180*84e33947SAndroid Build Coastguard Worker     }
181*84e33947SAndroid Build Coastguard Worker   }
182*84e33947SAndroid Build Coastguard Worker 
183*84e33947SAndroid Build Coastguard Worker   if (dispatched == true && error != CHPP_APP_ERROR_NONE) {
184*84e33947SAndroid Build Coastguard Worker     // Request was dispatched but an error was returned. Close out
185*84e33947SAndroid Build Coastguard Worker     // chppTimestampIncomingRequest()
186*84e33947SAndroid Build Coastguard Worker     chppTimestampOutgoingResponse(inReqState);
187*84e33947SAndroid Build Coastguard Worker   }
188*84e33947SAndroid Build Coastguard Worker 
189*84e33947SAndroid Build Coastguard Worker   return error;
190*84e33947SAndroid Build Coastguard Worker }
191*84e33947SAndroid Build Coastguard Worker 
192*84e33947SAndroid Build Coastguard Worker /**
193*84e33947SAndroid Build Coastguard Worker  * Initializes the WWAN service upon an open request from the client and
194*84e33947SAndroid Build Coastguard Worker  * responds to the client with the result.
195*84e33947SAndroid Build Coastguard Worker  *
196*84e33947SAndroid Build Coastguard Worker  * @param serviceContext Maintains status for each service instance.
197*84e33947SAndroid Build Coastguard Worker  * @param requestHeader App layer header of the request.
198*84e33947SAndroid Build Coastguard Worker  *
199*84e33947SAndroid Build Coastguard Worker  * @return Indicates the result of this function call.
200*84e33947SAndroid Build Coastguard Worker  */
chppWwanServiceOpen(struct ChppWwanServiceState * wwanServiceContext,struct ChppAppHeader * requestHeader)201*84e33947SAndroid Build Coastguard Worker static enum ChppAppErrorCode chppWwanServiceOpen(
202*84e33947SAndroid Build Coastguard Worker     struct ChppWwanServiceState *wwanServiceContext,
203*84e33947SAndroid Build Coastguard Worker     struct ChppAppHeader *requestHeader) {
204*84e33947SAndroid Build Coastguard Worker   static const struct chrePalWwanCallbacks palCallbacks = {
205*84e33947SAndroid Build Coastguard Worker       .cellInfoResultCallback = chppWwanServiceCellInfoResultCallback,
206*84e33947SAndroid Build Coastguard Worker   };
207*84e33947SAndroid Build Coastguard Worker 
208*84e33947SAndroid Build Coastguard Worker   enum ChppAppErrorCode error = CHPP_APP_ERROR_NONE;
209*84e33947SAndroid Build Coastguard Worker 
210*84e33947SAndroid Build Coastguard Worker   if (wwanServiceContext->service.openState == CHPP_OPEN_STATE_OPENED) {
211*84e33947SAndroid Build Coastguard Worker     CHPP_DEBUG_ASSERT_LOG(false, "WWAN service already open");
212*84e33947SAndroid Build Coastguard Worker     error = CHPP_APP_ERROR_INVALID_COMMAND;
213*84e33947SAndroid Build Coastguard Worker 
214*84e33947SAndroid Build Coastguard Worker   } else if (!wwanServiceContext->api->open(
215*84e33947SAndroid Build Coastguard Worker                  wwanServiceContext->service.appContext->systemApi,
216*84e33947SAndroid Build Coastguard Worker                  &palCallbacks)) {
217*84e33947SAndroid Build Coastguard Worker     CHPP_DEBUG_ASSERT_LOG(false, "WWAN PAL open failed");
218*84e33947SAndroid Build Coastguard Worker     error = CHPP_APP_ERROR_BEYOND_CHPP;
219*84e33947SAndroid Build Coastguard Worker 
220*84e33947SAndroid Build Coastguard Worker   } else {
221*84e33947SAndroid Build Coastguard Worker     CHPP_LOGD("WWAN service opened");
222*84e33947SAndroid Build Coastguard Worker     wwanServiceContext->service.openState = CHPP_OPEN_STATE_OPENED;
223*84e33947SAndroid Build Coastguard Worker 
224*84e33947SAndroid Build Coastguard Worker     struct ChppAppHeader *response =
225*84e33947SAndroid Build Coastguard Worker         chppAllocResponseFixed(requestHeader, struct ChppAppHeader);
226*84e33947SAndroid Build Coastguard Worker     size_t responseLen = sizeof(*response);
227*84e33947SAndroid Build Coastguard Worker 
228*84e33947SAndroid Build Coastguard Worker     if (response == NULL) {
229*84e33947SAndroid Build Coastguard Worker       CHPP_LOG_OOM();
230*84e33947SAndroid Build Coastguard Worker       error = CHPP_APP_ERROR_OOM;
231*84e33947SAndroid Build Coastguard Worker     } else {
232*84e33947SAndroid Build Coastguard Worker       chppSendTimestampedResponseOrFail(wwanServiceContext->service.appContext,
233*84e33947SAndroid Build Coastguard Worker                                         &wwanServiceContext->open, response,
234*84e33947SAndroid Build Coastguard Worker                                         responseLen);
235*84e33947SAndroid Build Coastguard Worker     }
236*84e33947SAndroid Build Coastguard Worker   }
237*84e33947SAndroid Build Coastguard Worker 
238*84e33947SAndroid Build Coastguard Worker   return error;
239*84e33947SAndroid Build Coastguard Worker }
240*84e33947SAndroid Build Coastguard Worker 
241*84e33947SAndroid Build Coastguard Worker /**
242*84e33947SAndroid Build Coastguard Worker  * Deinitializes the WWAN service.
243*84e33947SAndroid Build Coastguard Worker  *
244*84e33947SAndroid Build Coastguard Worker  * @param serviceContext Maintains status for each service instance.
245*84e33947SAndroid Build Coastguard Worker  * @param requestHeader App layer header of the request.
246*84e33947SAndroid Build Coastguard Worker  *
247*84e33947SAndroid Build Coastguard Worker  * @return Indicates the result of this function call.
248*84e33947SAndroid Build Coastguard Worker  */
chppWwanServiceClose(struct ChppWwanServiceState * wwanServiceContext,struct ChppAppHeader * requestHeader)249*84e33947SAndroid Build Coastguard Worker static enum ChppAppErrorCode chppWwanServiceClose(
250*84e33947SAndroid Build Coastguard Worker     struct ChppWwanServiceState *wwanServiceContext,
251*84e33947SAndroid Build Coastguard Worker     struct ChppAppHeader *requestHeader) {
252*84e33947SAndroid Build Coastguard Worker   enum ChppAppErrorCode error = CHPP_APP_ERROR_NONE;
253*84e33947SAndroid Build Coastguard Worker 
254*84e33947SAndroid Build Coastguard Worker   wwanServiceContext->api->close();
255*84e33947SAndroid Build Coastguard Worker   wwanServiceContext->service.openState = CHPP_OPEN_STATE_CLOSED;
256*84e33947SAndroid Build Coastguard Worker 
257*84e33947SAndroid Build Coastguard Worker   CHPP_LOGD("WWAN service closed");
258*84e33947SAndroid Build Coastguard Worker 
259*84e33947SAndroid Build Coastguard Worker   struct ChppAppHeader *response =
260*84e33947SAndroid Build Coastguard Worker       chppAllocResponseFixed(requestHeader, struct ChppAppHeader);
261*84e33947SAndroid Build Coastguard Worker   size_t responseLen = sizeof(*response);
262*84e33947SAndroid Build Coastguard Worker 
263*84e33947SAndroid Build Coastguard Worker   if (response == NULL) {
264*84e33947SAndroid Build Coastguard Worker     CHPP_LOG_OOM();
265*84e33947SAndroid Build Coastguard Worker     error = CHPP_APP_ERROR_OOM;
266*84e33947SAndroid Build Coastguard Worker   } else {
267*84e33947SAndroid Build Coastguard Worker     chppSendTimestampedResponseOrFail(wwanServiceContext->service.appContext,
268*84e33947SAndroid Build Coastguard Worker                                       &wwanServiceContext->close, response,
269*84e33947SAndroid Build Coastguard Worker                                       responseLen);
270*84e33947SAndroid Build Coastguard Worker   }
271*84e33947SAndroid Build Coastguard Worker 
272*84e33947SAndroid Build Coastguard Worker   return error;
273*84e33947SAndroid Build Coastguard Worker }
274*84e33947SAndroid Build Coastguard Worker 
275*84e33947SAndroid Build Coastguard Worker /**
276*84e33947SAndroid Build Coastguard Worker  * Notifies the service of an incoming reset.
277*84e33947SAndroid Build Coastguard Worker  *
278*84e33947SAndroid Build Coastguard Worker  * @param serviceContext Maintains status for each service instance.
279*84e33947SAndroid Build Coastguard Worker  */
chppWwanServiceNotifyReset(void * serviceContext)280*84e33947SAndroid Build Coastguard Worker static void chppWwanServiceNotifyReset(void *serviceContext) {
281*84e33947SAndroid Build Coastguard Worker   struct ChppWwanServiceState *wwanServiceContext =
282*84e33947SAndroid Build Coastguard Worker       (struct ChppWwanServiceState *)serviceContext;
283*84e33947SAndroid Build Coastguard Worker 
284*84e33947SAndroid Build Coastguard Worker   if (wwanServiceContext->service.openState != CHPP_OPEN_STATE_OPENED) {
285*84e33947SAndroid Build Coastguard Worker     CHPP_LOGW("WWAN service reset but wasn't open");
286*84e33947SAndroid Build Coastguard Worker   } else {
287*84e33947SAndroid Build Coastguard Worker     CHPP_LOGD("WWAN service reset. Closing");
288*84e33947SAndroid Build Coastguard Worker     wwanServiceContext->service.openState = CHPP_OPEN_STATE_CLOSED;
289*84e33947SAndroid Build Coastguard Worker     wwanServiceContext->api->close();
290*84e33947SAndroid Build Coastguard Worker   }
291*84e33947SAndroid Build Coastguard Worker }
292*84e33947SAndroid Build Coastguard Worker 
293*84e33947SAndroid Build Coastguard Worker /**
294*84e33947SAndroid Build Coastguard Worker  * Retrieves a set of flags indicating the WWAN features supported by the
295*84e33947SAndroid Build Coastguard Worker  * current implementation.
296*84e33947SAndroid Build Coastguard Worker  *
297*84e33947SAndroid Build Coastguard Worker  * @param serviceContext Maintains status for each service instance.
298*84e33947SAndroid Build Coastguard Worker  * @param requestHeader App layer header of the request.
299*84e33947SAndroid Build Coastguard Worker  *
300*84e33947SAndroid Build Coastguard Worker  * @return Indicates the result of this function call.
301*84e33947SAndroid Build Coastguard Worker  */
chppWwanServiceGetCapabilities(struct ChppWwanServiceState * wwanServiceContext,struct ChppAppHeader * requestHeader)302*84e33947SAndroid Build Coastguard Worker static enum ChppAppErrorCode chppWwanServiceGetCapabilities(
303*84e33947SAndroid Build Coastguard Worker     struct ChppWwanServiceState *wwanServiceContext,
304*84e33947SAndroid Build Coastguard Worker     struct ChppAppHeader *requestHeader) {
305*84e33947SAndroid Build Coastguard Worker   enum ChppAppErrorCode error = CHPP_APP_ERROR_NONE;
306*84e33947SAndroid Build Coastguard Worker 
307*84e33947SAndroid Build Coastguard Worker   struct ChppWwanGetCapabilitiesResponse *response = chppAllocResponseFixed(
308*84e33947SAndroid Build Coastguard Worker       requestHeader, struct ChppWwanGetCapabilitiesResponse);
309*84e33947SAndroid Build Coastguard Worker   size_t responseLen = sizeof(*response);
310*84e33947SAndroid Build Coastguard Worker 
311*84e33947SAndroid Build Coastguard Worker   if (response == NULL) {
312*84e33947SAndroid Build Coastguard Worker     CHPP_LOG_OOM();
313*84e33947SAndroid Build Coastguard Worker     error = CHPP_APP_ERROR_OOM;
314*84e33947SAndroid Build Coastguard Worker   } else {
315*84e33947SAndroid Build Coastguard Worker     response->params.capabilities = wwanServiceContext->api->getCapabilities();
316*84e33947SAndroid Build Coastguard Worker 
317*84e33947SAndroid Build Coastguard Worker     CHPP_LOGD("chppWwanServiceGetCapabilities returning 0x%" PRIx32
318*84e33947SAndroid Build Coastguard Worker               ", %" PRIuSIZE " bytes",
319*84e33947SAndroid Build Coastguard Worker               response->params.capabilities, responseLen);
320*84e33947SAndroid Build Coastguard Worker     chppSendTimestampedResponseOrFail(wwanServiceContext->service.appContext,
321*84e33947SAndroid Build Coastguard Worker                                       &wwanServiceContext->getCapabilities,
322*84e33947SAndroid Build Coastguard Worker                                       response, responseLen);
323*84e33947SAndroid Build Coastguard Worker   }
324*84e33947SAndroid Build Coastguard Worker 
325*84e33947SAndroid Build Coastguard Worker   return error;
326*84e33947SAndroid Build Coastguard Worker }
327*84e33947SAndroid Build Coastguard Worker 
328*84e33947SAndroid Build Coastguard Worker /**
329*84e33947SAndroid Build Coastguard Worker  * Query information about the current serving cell and its neighbors in
330*84e33947SAndroid Build Coastguard Worker  * response to a client request. This does not perform a network scan, but
331*84e33947SAndroid Build Coastguard Worker  * should return state from the current network registration data stored in the
332*84e33947SAndroid Build Coastguard Worker  * cellular modem.
333*84e33947SAndroid Build Coastguard Worker  *
334*84e33947SAndroid Build Coastguard Worker  * This function returns an error code synchronously. The requested cellular
335*84e33947SAndroid Build Coastguard Worker  * information shall be returned asynchronously to the client via the
336*84e33947SAndroid Build Coastguard Worker  * chppPlatformWwanCellInfoResultEvent() service response.
337*84e33947SAndroid Build Coastguard Worker  *
338*84e33947SAndroid Build Coastguard Worker  * @param serviceContext Maintains status for each service instance.
339*84e33947SAndroid Build Coastguard Worker  * @param requestHeader App layer header of the request.
340*84e33947SAndroid Build Coastguard Worker  *
341*84e33947SAndroid Build Coastguard Worker  * @return Indicates the result of this function call.
342*84e33947SAndroid Build Coastguard Worker  */
chppWwanServiceGetCellInfoAsync(struct ChppWwanServiceState * wwanServiceContext,struct ChppAppHeader * requestHeader)343*84e33947SAndroid Build Coastguard Worker static enum ChppAppErrorCode chppWwanServiceGetCellInfoAsync(
344*84e33947SAndroid Build Coastguard Worker     struct ChppWwanServiceState *wwanServiceContext,
345*84e33947SAndroid Build Coastguard Worker     struct ChppAppHeader *requestHeader) {
346*84e33947SAndroid Build Coastguard Worker   UNUSED_VAR(requestHeader);
347*84e33947SAndroid Build Coastguard Worker 
348*84e33947SAndroid Build Coastguard Worker   enum ChppAppErrorCode error = CHPP_APP_ERROR_NONE;
349*84e33947SAndroid Build Coastguard Worker 
350*84e33947SAndroid Build Coastguard Worker   if (!wwanServiceContext->api->requestCellInfo()) {
351*84e33947SAndroid Build Coastguard Worker     CHPP_LOGE(
352*84e33947SAndroid Build Coastguard Worker         "WWAN requestCellInfo PAL API failed. Unable to register for callback");
353*84e33947SAndroid Build Coastguard Worker     error = CHPP_APP_ERROR_UNSPECIFIED;
354*84e33947SAndroid Build Coastguard Worker   }
355*84e33947SAndroid Build Coastguard Worker 
356*84e33947SAndroid Build Coastguard Worker   return error;
357*84e33947SAndroid Build Coastguard Worker }
358*84e33947SAndroid Build Coastguard Worker 
359*84e33947SAndroid Build Coastguard Worker /**
360*84e33947SAndroid Build Coastguard Worker  * PAL callback to provide the result of a prior Request Cell Info
361*84e33947SAndroid Build Coastguard Worker  * (cellInfoResultCallback).
362*84e33947SAndroid Build Coastguard Worker  *
363*84e33947SAndroid Build Coastguard Worker  * @param result Scan results.
364*84e33947SAndroid Build Coastguard Worker  */
chppWwanServiceCellInfoResultCallback(struct chreWwanCellInfoResult * result)365*84e33947SAndroid Build Coastguard Worker static void chppWwanServiceCellInfoResultCallback(
366*84e33947SAndroid Build Coastguard Worker     struct chreWwanCellInfoResult *result) {
367*84e33947SAndroid Build Coastguard Worker   // Recover state
368*84e33947SAndroid Build Coastguard Worker   struct ChppIncomingRequestState *inReqState =
369*84e33947SAndroid Build Coastguard Worker       &gWwanServiceContext.getCellInfoAsync;
370*84e33947SAndroid Build Coastguard Worker   struct ChppWwanServiceState *wwanServiceContext =
371*84e33947SAndroid Build Coastguard Worker       container_of(inReqState, struct ChppWwanServiceState, getCellInfoAsync);
372*84e33947SAndroid Build Coastguard Worker 
373*84e33947SAndroid Build Coastguard Worker   // Craft response per parser script
374*84e33947SAndroid Build Coastguard Worker   struct ChppWwanCellInfoResultWithHeader *response = NULL;
375*84e33947SAndroid Build Coastguard Worker   size_t responseLen = 0;
376*84e33947SAndroid Build Coastguard Worker   if (!chppWwanCellInfoResultFromChre(result, &response, &responseLen)) {
377*84e33947SAndroid Build Coastguard Worker     CHPP_LOGE("CellInfo conversion failed (OOM?) ID=%" PRIu8,
378*84e33947SAndroid Build Coastguard Worker               inReqState->transaction);
379*84e33947SAndroid Build Coastguard Worker 
380*84e33947SAndroid Build Coastguard Worker     response = chppMalloc(sizeof(struct ChppAppHeader));
381*84e33947SAndroid Build Coastguard Worker     if (response == NULL) {
382*84e33947SAndroid Build Coastguard Worker       CHPP_LOG_OOM();
383*84e33947SAndroid Build Coastguard Worker     } else {
384*84e33947SAndroid Build Coastguard Worker       responseLen = sizeof(struct ChppAppHeader);
385*84e33947SAndroid Build Coastguard Worker     }
386*84e33947SAndroid Build Coastguard Worker   }
387*84e33947SAndroid Build Coastguard Worker 
388*84e33947SAndroid Build Coastguard Worker   if (response != NULL) {
389*84e33947SAndroid Build Coastguard Worker     response->header.handle = wwanServiceContext->service.handle;
390*84e33947SAndroid Build Coastguard Worker     response->header.type = CHPP_MESSAGE_TYPE_SERVICE_RESPONSE;
391*84e33947SAndroid Build Coastguard Worker     response->header.transaction = inReqState->transaction;
392*84e33947SAndroid Build Coastguard Worker     response->header.error = (responseLen > sizeof(struct ChppAppHeader))
393*84e33947SAndroid Build Coastguard Worker                                  ? CHPP_APP_ERROR_NONE
394*84e33947SAndroid Build Coastguard Worker                                  : CHPP_APP_ERROR_CONVERSION_FAILED;
395*84e33947SAndroid Build Coastguard Worker     response->header.command = CHPP_WWAN_GET_CELLINFO_ASYNC;
396*84e33947SAndroid Build Coastguard Worker 
397*84e33947SAndroid Build Coastguard Worker     chppSendTimestampedResponseOrFail(wwanServiceContext->service.appContext,
398*84e33947SAndroid Build Coastguard Worker                                       inReqState, response, responseLen);
399*84e33947SAndroid Build Coastguard Worker   }
400*84e33947SAndroid Build Coastguard Worker 
401*84e33947SAndroid Build Coastguard Worker   gWwanServiceContext.api->releaseCellInfoResult(result);
402*84e33947SAndroid Build Coastguard Worker }
403*84e33947SAndroid Build Coastguard Worker 
404*84e33947SAndroid Build Coastguard Worker /************************************************
405*84e33947SAndroid Build Coastguard Worker  *  Public Functions
406*84e33947SAndroid Build Coastguard Worker  ***********************************************/
407*84e33947SAndroid Build Coastguard Worker 
chppRegisterWwanService(struct ChppAppState * appContext)408*84e33947SAndroid Build Coastguard Worker void chppRegisterWwanService(struct ChppAppState *appContext) {
409*84e33947SAndroid Build Coastguard Worker   gWwanServiceContext.api = chrePalWwanGetApi(CHPP_PAL_WWAN_API_VERSION);
410*84e33947SAndroid Build Coastguard Worker 
411*84e33947SAndroid Build Coastguard Worker   if (gWwanServiceContext.api == NULL) {
412*84e33947SAndroid Build Coastguard Worker     CHPP_DEBUG_ASSERT_LOG(false,
413*84e33947SAndroid Build Coastguard Worker                           "WWAN PAL API incompatible. Cannot register service");
414*84e33947SAndroid Build Coastguard Worker 
415*84e33947SAndroid Build Coastguard Worker   } else {
416*84e33947SAndroid Build Coastguard Worker     chppRegisterService(appContext, (void *)&gWwanServiceContext,
417*84e33947SAndroid Build Coastguard Worker                         &gWwanServiceContext.service, NULL /*outReqStates*/,
418*84e33947SAndroid Build Coastguard Worker                         &kWwanServiceConfig);
419*84e33947SAndroid Build Coastguard Worker     CHPP_DEBUG_ASSERT(gWwanServiceContext.service.handle);
420*84e33947SAndroid Build Coastguard Worker   }
421*84e33947SAndroid Build Coastguard Worker }
422*84e33947SAndroid Build Coastguard Worker 
chppDeregisterWwanService(struct ChppAppState * appContext)423*84e33947SAndroid Build Coastguard Worker void chppDeregisterWwanService(struct ChppAppState *appContext) {
424*84e33947SAndroid Build Coastguard Worker   // TODO
425*84e33947SAndroid Build Coastguard Worker 
426*84e33947SAndroid Build Coastguard Worker   UNUSED_VAR(appContext);
427*84e33947SAndroid Build Coastguard Worker }
428