rjw | 1f88458 | 2022-01-06 17:20:42 +0800 | [diff] [blame^] | 1 | /* Copyright Statement: |
| 2 | * |
| 3 | * This software/firmware and related documentation ("MediaTek Software") are |
| 4 | * protected under relevant copyright laws. The information contained herein |
| 5 | * is confidential and proprietary to MediaTek Inc. and/or its licensors. |
| 6 | * Without the prior written permission of MediaTek inc. and/or its licensors, |
| 7 | * any reproduction, modification, use or disclosure of MediaTek Software, |
| 8 | * and information contained herein, in whole or in part, shall be strictly prohibited. |
| 9 | */ |
| 10 | /* MediaTek Inc. (C) 2010. All rights reserved. |
| 11 | * |
| 12 | * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES |
| 13 | * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") |
| 14 | * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON |
| 15 | * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, |
| 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF |
| 17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. |
| 18 | * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE |
| 19 | * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR |
| 20 | * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH |
| 21 | * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES |
| 22 | * THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES |
| 23 | * CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK |
| 24 | * SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR |
| 25 | * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND |
| 26 | * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE, |
| 27 | * AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE, |
| 28 | * OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO |
| 29 | * MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. |
| 30 | * |
| 31 | * The following software/firmware and/or related documentation ("MediaTek Software") |
| 32 | * have been modified by MediaTek Inc. All revisions are subject to any receiver's |
| 33 | * applicable license agreements with MediaTek Inc. |
| 34 | */ |
| 35 | #include <string.h> |
| 36 | #include <stdio.h> |
| 37 | #include <sys/types.h> |
| 38 | #include <sys/socket.h> |
| 39 | #include <sys/un.h> |
| 40 | #include <signal.h> |
| 41 | #include <errno.h> |
| 42 | #include <stdlib.h> |
| 43 | #include <unistd.h> |
| 44 | #include <vendor-ril/telephony/ril.h> |
| 45 | |
| 46 | #include "common.h" |
| 47 | #include "util/utils.h" |
| 48 | #include "atci/ATCI.h" |
| 49 | #include "atci_util.h" |
| 50 | #include "atci_at_util.h" |
| 51 | #include "Radio_capability_switch_util.h" |
| 52 | |
| 53 | #ifdef ATCI_PARSE |
| 54 | #include "atci_sys_cmd.h" |
| 55 | #include "atci_ss_cmd.h" |
| 56 | #include "atci_cc_cmd.h" |
| 57 | #endif |
| 58 | |
| 59 | struct sockaddr_un atci_server_addr; |
| 60 | //struct sockaddr_in atci_server_addr; |
| 61 | //struct sockaddr_un atci_client_addr; |
| 62 | #undef LOG_TAG |
| 63 | #define LOG_TAG "DEMO_ATCI" |
| 64 | |
| 65 | #if ATCI_ENABLE_RESPONSE |
| 66 | char Respose_buf[RESPONSE_BUF_SIZE]; |
| 67 | #endif |
| 68 | |
| 69 | #ifdef ATCI_PARSE |
| 70 | int atci_dispatch_cmd(char *line); |
| 71 | #endif |
| 72 | |
| 73 | int atci_server_socket_fd, atci_client_connect; |
| 74 | namespace android { |
| 75 | extern int s_registerCalled; |
| 76 | } |
| 77 | |
| 78 | #define SOCKET_ZERO 0 |
| 79 | #define SOCKET_SUCC 1 |
| 80 | #define SOCKET_FAIL -1 |
| 81 | static int ATCI_Token = 0; |
| 82 | |
| 83 | int ATCISupport(int request) { |
| 84 | switch (request) { |
| 85 | case TELEPHONY_REQUEST_SET_CALL_FORWARD: |
| 86 | return 1; |
| 87 | case TELEPHONY_REQUEST_SET_CALL_WAITING: |
| 88 | return 1; |
| 89 | case TELEPHONY_REQUEST_SET_CALL_BARRING: |
| 90 | return 1; |
| 91 | case TELEPHONY_REQUEST_DIAL: |
| 92 | return 1; |
| 93 | case TELEPHONY_REQUEST_DROP_CONF_CALL_MEMBER: |
| 94 | return 1; |
| 95 | case TELEPHONY_REQUEST_FLIGHT: |
| 96 | return 1; |
| 97 | case TELEPHONY_REQUEST_SET_MUTE: |
| 98 | return 1; |
| 99 | case TELEPHONY_REQUEST_MERGE_CONF_CALLS: |
| 100 | return 1; |
| 101 | case TELEPHONY_REQUEST_CREATE_IMS_CONF_CALL: |
| 102 | return 1; |
| 103 | case TELEPHONY_REQUEST_DIAL_WITH_SIP_URI: |
| 104 | return 1; |
| 105 | default: |
| 106 | return 0; |
| 107 | } |
| 108 | } |
| 109 | const char * ATCIReqRspToString(int request) { |
| 110 | switch (request) { |
| 111 | case TELEPHONY_REQUEST_SET_CALL_FORWARD: |
| 112 | return "SET_CALL_FORWARD"; |
| 113 | case TELEPHONY_REQUEST_SET_CALL_WAITING: |
| 114 | return "SET_CALL_WAITING"; |
| 115 | case TELEPHONY_REQUEST_SET_CALL_BARRING: |
| 116 | return "SET_CALL_BARRING"; |
| 117 | case TELEPHONY_REQUEST_DIAL: |
| 118 | return "DIAL"; |
| 119 | case TELEPHONY_REQUEST_DROP_CONF_CALL_MEMBER: |
| 120 | return "DROP_CONF_CALL_MEMBER"; |
| 121 | case TELEPHONY_REQUEST_FLIGHT: |
| 122 | return "FLIGHT"; |
| 123 | case TELEPHONY_RESPONSE_FLIGHT: |
| 124 | return "RSP_FLIGHT"; |
| 125 | case TELEPHONY_REQUEST_SET_MUTE: |
| 126 | return "SET_MUTE"; |
| 127 | case TELEPHONY_REQUEST_MERGE_CONF_CALLS: |
| 128 | return "MERGE_CONF_CALLS"; |
| 129 | case TELEPHONY_REQUEST_CREATE_IMS_CONF_CALL: |
| 130 | return "CREATE_IMS_CONF_CALL"; |
| 131 | case TELEPHONY_REQUEST_DIAL_WITH_SIP_URI: |
| 132 | return "DIAL_WITH_SIP_URI"; |
| 133 | default: |
| 134 | return "<unknown request>"; |
| 135 | } |
| 136 | } |
| 137 | //return requestNumber |
| 138 | int ATCIParserRequest(int request) { |
| 139 | //char* cPoint = buf; |
| 140 | //int reqNum = 0; |
| 141 | |
| 142 | RLOGD("ATCI Parser request number start!"); |
| 143 | |
| 144 | //memcpy(&reqNum,cPoint,sizeof(int)); |
| 145 | RLOGD("Request is %d,%s", request, ATCIReqRspToString(request)); |
| 146 | |
| 147 | if (ATCISupport(request) != 1) |
| 148 | return -1; |
| 149 | |
| 150 | return request; |
| 151 | } |
| 152 | |
| 153 | int MappingATCI2RIL(int reqNum) { |
| 154 | int request = 0; |
| 155 | switch (reqNum) { |
| 156 | case TELEPHONY_REQUEST_SET_CALL_FORWARD: |
| 157 | request = RIL_REQUEST_SET_CALL_FORWARD; |
| 158 | break; |
| 159 | case TELEPHONY_REQUEST_SET_CALL_WAITING: |
| 160 | request = RIL_REQUEST_SET_CALL_WAITING; |
| 161 | break; |
| 162 | case TELEPHONY_REQUEST_SET_CALL_BARRING: |
| 163 | request = RIL_REQUEST_SET_FACILITY_LOCK; |
| 164 | break; |
| 165 | case TELEPHONY_REQUEST_DIAL: |
| 166 | request = RIL_REQUEST_DIAL; |
| 167 | break; |
| 168 | case TELEPHONY_REQUEST_DROP_CONF_CALL_MEMBER: |
| 169 | request = RIL_REQUEST_REMOVE_IMS_CONFERENCE_CALL_MEMBER; |
| 170 | break; |
| 171 | case TELEPHONY_REQUEST_FLIGHT: |
| 172 | request = RIL_REQUEST_RADIO_POWER; |
| 173 | break; |
| 174 | case TELEPHONY_REQUEST_SET_MUTE: |
| 175 | request = RIL_REQUEST_SET_MUTE; |
| 176 | break; |
| 177 | case TELEPHONY_REQUEST_MERGE_CONF_CALLS: |
| 178 | request = RIL_REQUEST_CONFERENCE; |
| 179 | break; |
| 180 | case TELEPHONY_REQUEST_CREATE_IMS_CONF_CALL: |
| 181 | request = RIL_REQUEST_CONFERENCE_DIAL; |
| 182 | break; |
| 183 | case TELEPHONY_REQUEST_DIAL_WITH_SIP_URI: |
| 184 | request = RIL_REQUEST_DIAL_WITH_SIP_URI; |
| 185 | break; |
| 186 | default: |
| 187 | request = -1; |
| 188 | } |
| 189 | |
| 190 | return request; |
| 191 | } |
| 192 | |
| 193 | int MappingParameter(int reqNum, int length, char* data, char* buf, |
| 194 | char** argv) { |
| 195 | int argc = 1; |
| 196 | char* cPoint; |
| 197 | |
| 198 | cPoint = buf; |
| 199 | switch (reqNum) { |
| 200 | case TELEPHONY_REQUEST_SET_CALL_FORWARD: { |
| 201 | if (length != sizeof(telephonyRequestSetCallForward)) { |
| 202 | RLOGD("Set_Call_Forward data error!"); |
| 203 | return -1; |
| 204 | } |
| 205 | telephonyRequestSetCallForward tempSCF; |
| 206 | memset(&tempSCF, 0, sizeof(tempSCF)); |
| 207 | memcpy(&tempSCF, data, length); |
| 208 | |
| 209 | //cmd parameter sequence: status, reason, number, time_seconds, service_class; other not need. |
| 210 | argv[1] = cPoint; //status |
| 211 | cPoint += sizeof(tempSCF.status); |
| 212 | sprintf(argv[1], "%d", tempSCF.status); |
| 213 | |
| 214 | argv[2] = cPoint; //reason |
| 215 | cPoint += sizeof(tempSCF.reason); |
| 216 | sprintf(argv[2], "%d", tempSCF.reason); |
| 217 | |
| 218 | argv[5] = cPoint; //service_class |
| 219 | cPoint += sizeof(tempSCF.service_class); |
| 220 | sprintf(argv[5], "%d", tempSCF.service_class); |
| 221 | |
| 222 | argv[6] = cPoint; //toa |
| 223 | cPoint += sizeof(tempSCF.toa); |
| 224 | sprintf(argv[6], "%d", tempSCF.toa); |
| 225 | |
| 226 | argv[3] = cPoint; //number |
| 227 | cPoint += sizeof(tempSCF.number); |
| 228 | sprintf(argv[3], "%s", tempSCF.number); |
| 229 | |
| 230 | argv[4] = cPoint; //time_seconds |
| 231 | sprintf(argv[4], "%d", tempSCF.time_seconds); |
| 232 | |
| 233 | argc += 5; |
| 234 | RLOGD( |
| 235 | "TELEPHONY_REQUEST_SET_CALL_FORWARD status(%s) reason(%s) number(%s) time_seconds(%s) service_class(%s) --toa(%s)", |
| 236 | argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]); |
| 237 | } |
| 238 | break; |
| 239 | case TELEPHONY_REQUEST_SET_CALL_WAITING: { |
| 240 | if (length != sizeof(telephonyRequestSetCallWaiting)) { |
| 241 | RLOGD("Set_Call_Waiting data error!"); |
| 242 | return -1; |
| 243 | } |
| 244 | telephonyRequestSetCallWaiting tempSCW; |
| 245 | memset(&tempSCW, 0, sizeof(tempSCW)); |
| 246 | memcpy(&tempSCW, data, length); |
| 247 | |
| 248 | //cmd parameter sequence: statue, service_code |
| 249 | argv[1] = cPoint; //status |
| 250 | cPoint += sizeof(tempSCW.status); |
| 251 | sprintf(argv[1], "%d", tempSCW.status); |
| 252 | |
| 253 | argv[2] = cPoint; //service_class |
| 254 | sprintf(argv[2], "%d", tempSCW.service_class); |
| 255 | |
| 256 | argc += 2; |
| 257 | RLOGD("TELEPHONY_REQUEST_SET_CALL_WAITING status(%s) service_class(%s)", |
| 258 | argv[1], argv[2]); |
| 259 | } |
| 260 | break; |
| 261 | case TELEPHONY_REQUEST_SET_CALL_BARRING: { |
| 262 | if (length != sizeof(telephonyRequestSetCallBarring)) { |
| 263 | RLOGD("Set_Call_Barring data error!"); |
| 264 | return -1; |
| 265 | } |
| 266 | telephonyRequestSetCallBarring tempSCB; |
| 267 | memset(&tempSCB, 0, sizeof(tempSCB)); |
| 268 | memcpy(&tempSCB, data, length); |
| 269 | |
| 270 | //cmd parameter sequence: facility, password, serviceclass,enable; other not need. |
| 271 | argv[4] = cPoint; //status |
| 272 | cPoint += sizeof(tempSCB.status); |
| 273 | sprintf(argv[4], "%d", tempSCB.status); |
| 274 | |
| 275 | argv[1] = cPoint; //facility |
| 276 | cPoint += sizeof(tempSCB.facility); |
| 277 | sprintf(argv[1], "%s", tempSCB.facility); |
| 278 | |
| 279 | argv[2] = cPoint; //password |
| 280 | cPoint += sizeof(tempSCB.password); |
| 281 | sprintf(argv[2], "%s", tempSCB.password); |
| 282 | |
| 283 | argv[3] = cPoint; //serviceclass |
| 284 | cPoint += sizeof(tempSCB.serviceClass); |
| 285 | sprintf(argv[3], "%d", tempSCB.serviceClass); |
| 286 | |
| 287 | argc += 4; |
| 288 | RLOGD( |
| 289 | "TELEPHONY_REQUEST_SET_CALL_Barring facility(%s) password(%s) service_class(%s) status(enable)(%s)", |
| 290 | argv[1], argv[2], argv[3], argv[4]); |
| 291 | } |
| 292 | break; |
| 293 | case TELEPHONY_REQUEST_DIAL: { |
| 294 | if (length != sizeof(telephonyRequestDial)) { |
| 295 | RLOGD("Request dail data error!"); |
| 296 | return -1; |
| 297 | } |
| 298 | telephonyRequestDial tempDIAL; |
| 299 | memset(&tempDIAL, 0, sizeof(tempDIAL)); |
| 300 | memcpy(&tempDIAL, data, length); |
| 301 | |
| 302 | //cmd parameter sequence: callnumber, clir; |
| 303 | argv[2] = cPoint; //clir |
| 304 | cPoint += sizeof(tempDIAL.clir); |
| 305 | sprintf(argv[2], "%d", tempDIAL.clir); |
| 306 | |
| 307 | argv[1] = cPoint; //phonyNumber |
| 308 | sprintf(argv[1], "%s", tempDIAL.phonyNumber); |
| 309 | |
| 310 | argc += 2; |
| 311 | RLOGD("TELEPHONY_REQUEST_DIAL CLIR(%s) PhoneNumber(%s)", argv[2], argv[1]); |
| 312 | } |
| 313 | break; |
| 314 | case TELEPHONY_REQUEST_DROP_CONF_CALL_MEMBER: { |
| 315 | if (length != sizeof(telephonyRequestDropConfCallMember)) { |
| 316 | RLOGD("DropConfCallMember data error!"); |
| 317 | return -1; |
| 318 | } |
| 319 | telephonyRequestDropConfCallMember tempDCCM; |
| 320 | memset(&tempDCCM, 0, sizeof(tempDCCM)); |
| 321 | memcpy(&tempDCCM, data, length); |
| 322 | |
| 323 | //cmd parameter sequence: callId, addr, ToAdd; other not need. |
| 324 | argv[1] = cPoint; //ConfCallID |
| 325 | cPoint += sizeof(tempDCCM.confCallID); |
| 326 | sprintf(argv[1], "%d", tempDCCM.confCallID); |
| 327 | |
| 328 | argv[2] = cPoint; //phonyNumber |
| 329 | cPoint += sizeof(tempDCCM.phonyNumber); |
| 330 | sprintf(argv[2], "%d", tempDCCM.phonyNumber); |
| 331 | |
| 332 | argv[3] = cPoint; //callIDToAdd |
| 333 | sprintf(argv[3], "%d", tempDCCM.callIDToAdd); |
| 334 | |
| 335 | argc += 3; |
| 336 | RLOGD( |
| 337 | "TELEPHONY_REQUEST_DROP_CONF_CALL_MEMBER ConfCallID(%s) phonyNumber(%s) callIDToAdd(%s)", |
| 338 | argv[1], argv[2], argv[3]); |
| 339 | } |
| 340 | break; |
| 341 | case TELEPHONY_REQUEST_FLIGHT: { |
| 342 | if (length != sizeof(telephonyRequestFlight)) { |
| 343 | RLOGD("Request flight data error!"); |
| 344 | return -1; |
| 345 | } |
| 346 | telephonyRequestFlight tempFT; |
| 347 | memset(&tempFT, 0, sizeof(tempFT)); |
| 348 | memcpy(&tempFT, data, length); |
| 349 | |
| 350 | //cmd parameter sequence: mode. |
| 351 | argv[1] = cPoint; //flightModeOn |
| 352 | sprintf(argv[1], "%d", (tempFT.flightModeOn == 1 ? 0 : 1)); |
| 353 | |
| 354 | argc += 1; |
| 355 | RLOGD("TELEPHONY_REQUEST_FLIGHT flight Mode is %s-->(%s)", |
| 356 | (tempFT.flightModeOn == 1 ? "On" : "Off"), argv[1]); |
| 357 | } |
| 358 | break; |
| 359 | case TELEPHONY_REQUEST_SET_MUTE: { |
| 360 | if (length != sizeof(telephonyRequestSetMute)) { |
| 361 | RLOGD("Request flight data error!"); |
| 362 | return -1; |
| 363 | } |
| 364 | telephonyRequestSetMute tempSM; |
| 365 | memset(&tempSM, 0, sizeof(tempSM)); |
| 366 | memcpy(&tempSM, data, length); |
| 367 | |
| 368 | //cmd parameter sequence: mode. |
| 369 | argv[1] = cPoint; //isMute |
| 370 | sprintf(argv[1], "%d", tempSM.isMute); |
| 371 | |
| 372 | argc += 1; |
| 373 | RLOGD("TELEPHONY_REQUERT_SET_MUTE isMute(%s)", argv[1]); |
| 374 | } |
| 375 | break; |
| 376 | case TELEPHONY_REQUEST_MERGE_CONF_CALLS: { |
| 377 | RLOGD("TELEPHONY_REQUERT_MERGE_CONF_CALLS (No Parm.)"); |
| 378 | } |
| 379 | break; |
| 380 | case TELEPHONY_REQUEST_CREATE_IMS_CONF_CALL: { |
| 381 | //cmd parameter sequence: DialMethod, ParticipantsNumber, addresses, clir; |
| 382 | argv[1] = cPoint; //DialMethod |
| 383 | sprintf(argv[1], "%d", 0); |
| 384 | cPoint += sizeof(int); |
| 385 | |
| 386 | argv[2] = cPoint; //ParticipantsNumber |
| 387 | sprintf(argv[2], "%d", 0); |
| 388 | cPoint += sizeof(int); |
| 389 | //no address |
| 390 | argv[3] = cPoint; //CLIR |
| 391 | sprintf(argv[2], "%s", "0"); |
| 392 | |
| 393 | argc += 3; |
| 394 | RLOGD( |
| 395 | "TELEPHONY_REQUEST_CREATE_IMS_CONF_CALL dialMethod(%d) PhoneNumber(%d),clir(%s)", |
| 396 | argv[1], argv[2], argv[3]); |
| 397 | } |
| 398 | break; |
| 399 | case TELEPHONY_REQUEST_DIAL_WITH_SIP_URI: { |
| 400 | if (length != sizeof(telephonyRequestDial)) //struct with the same as DIAL |
| 401 | { |
| 402 | RLOGD("Request DialWithSipUri data error!"); |
| 403 | return -1; |
| 404 | } |
| 405 | telephonyRequestDial tempDWSU; |
| 406 | memset(&tempDWSU, 0, sizeof(tempDWSU)); |
| 407 | memcpy(&tempDWSU, data, length); |
| 408 | |
| 409 | //cmd parameter sequence: address, clir; |
| 410 | argv[2] = cPoint; //clir |
| 411 | cPoint += sizeof(tempDWSU.clir); |
| 412 | sprintf(argv[2], "%d", tempDWSU.clir); |
| 413 | |
| 414 | argv[1] = cPoint; //address |
| 415 | sprintf(argv[1], "%s", tempDWSU.phonyNumber); |
| 416 | |
| 417 | argc += 2; |
| 418 | RLOGD("TELEPHONY_REQUEST_DIAL_WITH_SIP_URI CLIR(%d) PhoneNumber(%s)", |
| 419 | argv[2], argv[1]); |
| 420 | } |
| 421 | break; |
| 422 | default: |
| 423 | break; |
| 424 | } |
| 425 | |
| 426 | return argc; |
| 427 | } |
| 428 | |
| 429 | void ATCIResponse(int token, int error, char* data, int reqNum) |
| 430 | { |
| 431 | //int reqNum; |
| 432 | char buf[64]; |
| 433 | if(token&ATCI_TOKEN_MARK != ATCI_TOKEN_MARK) { |
| 434 | if(token == 0 && data == NULL && reqNum == 0) { |
| 435 | RLOGD("AT%RESTART: %d", error); |
| 436 | } else { |
| 437 | RLOGE("ATCIRespnse Error, Token not ATCI\n"); |
| 438 | } |
| 439 | |
| 440 | } else { |
| 441 | RLOGD("token is %d,%s",reqNum,android::requestToString(reqNum)); |
| 442 | } |
| 443 | |
| 444 | memset(buf, 0, sizeof(buf)); |
| 445 | if(error == 1){ |
| 446 | sprintf(buf,"%s","ERROR"); |
| 447 | } else { |
| 448 | sprintf(buf,"%s","OK"); |
| 449 | } |
| 450 | |
| 451 | int len_s = send(atci_client_connect, buf, strlen(buf), 0); |
| 452 | RLOGD("Response Buf is %s, send length is %d",buf,len_s); |
| 453 | } |
| 454 | |
| 455 | #ifdef ATCI_PARSE |
| 456 | int acti_cmd_recv(int fd, char *buf, int len) { |
| 457 | int ret = 0; |
| 458 | fd_set rfds; |
| 459 | //FD_CLR(fd, &rfds); |
| 460 | FD_SET(fd, &rfds); |
| 461 | ret = select(fd + 1, &rfds, NULL, NULL, NULL); |
| 462 | if (ret <= 0) { |
| 463 | RLOGE("acti_cmd_recv select error, ret=%d, error=%s(%d),fd=%d", ret, |
| 464 | strerror(errno), errno, fd); |
| 465 | return SOCKET_FAIL; |
| 466 | } |
| 467 | if (FD_ISSET(fd, &rfds)) { |
| 468 | ret = recv(fd, buf, len, 0); |
| 469 | if (ret < 0) { |
| 470 | RLOGE("acti_cmd_recv select error, ret=%d, error=%s(%d),fd=%d", ret, |
| 471 | strerror(errno), errno, fd); |
| 472 | return SOCKET_FAIL; |
| 473 | } else if (ret == 0) { |
| 474 | RLOGE("acti_cmd_recv recv error, ret=%d, error=%s(%d),fd=%d", ret, |
| 475 | strerror(errno), errno, fd); |
| 476 | return SOCKET_ZERO; |
| 477 | } else { |
| 478 | //buf[ret] = '\0'; |
| 479 | } |
| 480 | |
| 481 | } |
| 482 | return SOCKET_SUCC; |
| 483 | } |
| 484 | #endif |
| 485 | |
| 486 | int atci_sock_recv(int fd, char *buf, int len) { |
| 487 | int ret = 0; |
| 488 | int offset = 0; |
| 489 | |
| 490 | while (offset < len) { |
| 491 | fd_set rfds; |
| 492 | FD_SET(fd, &rfds); |
| 493 | ret = select(fd + 1, &rfds, NULL, NULL, NULL); |
| 494 | if (ret < 0) { |
| 495 | if (errno == EINTR || errno == EAGAIN) { |
| 496 | continue; |
| 497 | } |
| 498 | RLOGE("atci_sock_recv select error, ret=%d, error=%s(%d),fd=%d", ret, |
| 499 | strerror(errno), errno, fd); |
| 500 | return SOCKET_FAIL; |
| 501 | } else if (ret == 0) { |
| 502 | continue; |
| 503 | } |
| 504 | if (FD_ISSET(fd, &rfds)) { |
| 505 | ret = recv(fd, buf + offset, len - offset, 0); |
| 506 | if (ret < 0) { |
| 507 | RLOGE("atci_sock_recv recv error, ret=%d, error=%s(%d),fd=%d", ret, |
| 508 | strerror(errno), errno, fd); |
| 509 | return SOCKET_FAIL; |
| 510 | } else if (ret == 0) { |
| 511 | RLOGE("atci_sock_recv recv error, ret=%d, error=%s(%d),fd=%d", ret, |
| 512 | strerror(errno), errno, fd); |
| 513 | return SOCKET_ZERO; |
| 514 | } |
| 515 | offset += ret; |
| 516 | } |
| 517 | } |
| 518 | return SOCKET_SUCC; |
| 519 | } |
| 520 | |
| 521 | void sendAtciRequest(int request, char* reqStr, int argc, char** argv) { |
| 522 | //for dsds, should close two slot radio. |
| 523 | if(utils::is_support_dsds() && (request == RIL_REQUEST_RADIO_POWER)){ |
| 524 | int enable = atoi(argv[1])? 1 : 0; |
| 525 | for(int i = 0; i < 2; i++) { |
| 526 | //For GCF, enhance AT%Flight=0. only SIM is inserted, radio can open. |
| 527 | if(enable){ |
| 528 | if (Radio_capability_switch_util::is_sim_inserted(i)) { |
| 529 | RequestInfo* pRI = (RequestInfo*) (calloc(1, sizeof(RequestInfo))); |
| 530 | pRI->socket_id = (RIL_SOCKET_ID)i; |
| 531 | android::ATCIRequest(request, reqStr, (void*) (pRI), argc, argv); |
| 532 | } { |
| 533 | RLOGD("ignore radio power on command because of absent SIM Card"); |
| 534 | } |
| 535 | } else { |
| 536 | RequestInfo* pRI = (RequestInfo*) (calloc(1, sizeof(RequestInfo))); |
| 537 | pRI->socket_id = (RIL_SOCKET_ID)i; |
| 538 | android::ATCIRequest(request, reqStr, (void*) (pRI), argc, argv); |
| 539 | } |
| 540 | } |
| 541 | } else { |
| 542 | RequestInfo* pRI = (RequestInfo*) (calloc(1, sizeof(RequestInfo))); |
| 543 | android::ATCIRequest(request, reqStr, (void*) (pRI), argc, argv); |
| 544 | } |
| 545 | return; |
| 546 | } |
| 547 | |
| 548 | void * StartATCISocket(void *param) { |
| 549 | RLOGD("StartATCISocket start\n"); |
| 550 | socklen_t server_len, client_len; |
| 551 | struct sockaddr_un atci_client_addr; |
| 552 | //struct sockaddr_in atci_client_addr; |
| 553 | char parser_buf[SOCKET_BUF_SIZE]; |
| 554 | char *argv[ATCI_MAX_ARGS]; |
| 555 | int argc = 0; |
| 556 | |
| 557 | prctl(PR_SET_NAME, (unsigned long) "ATCI_Thr"); |
| 558 | |
| 559 | /* create socket */ |
| 560 | unlink(ATCI_SERVER_SOCKET); |
| 561 | atci_server_socket_fd = socket(AF_UNIX, SOCK_STREAM, 0); |
| 562 | //atci_server_socket_fd = socket(AF_INET, SOCK_STREAM, 0); |
| 563 | if (atci_server_socket_fd == -1) { |
| 564 | RLOGE("Create ATCI Socket Failed:"); |
| 565 | exit(1); |
| 566 | } |
| 567 | memset(&atci_server_addr, 0, sizeof(atci_server_addr)); |
| 568 | atci_server_addr.sun_family = AF_UNIX; |
| 569 | //atci_server_addr.sin_family = AF_INET; |
| 570 | //atci_server_addr.sin_addr.s_addr = htonl(INADDR_ANY); |
| 571 | //atci_server_addr.sin_port = htons(10004); |
| 572 | strcpy(atci_server_addr.sun_path, ATCI_SERVER_SOCKET); |
| 573 | server_len = sizeof(atci_server_addr); |
| 574 | /* bind socket port*/ |
| 575 | if (-1 |
| 576 | == bind(atci_server_socket_fd, (struct sockaddr *) &atci_server_addr, |
| 577 | server_len)) { |
| 578 | RLOGE("Server Bind Failed:"); |
| 579 | exit(1); |
| 580 | } |
| 581 | |
| 582 | if (listen(atci_server_socket_fd, 1) == -1) { |
| 583 | RLOGE("listen fail!"); |
| 584 | close(atci_server_socket_fd); |
| 585 | exit(1); |
| 586 | } |
| 587 | #ifdef ATCI_PARSE |
| 588 | DbgMsg("init cmd handle"); |
| 589 | if(/*atci_generic_init(NULL)||*/atci_cc_init(NULL)||atci_ss_init(NULL)||atci_sys_init(NULL)) { |
| 590 | ErrMsg("module init function error,exit"); |
| 591 | exit(-1); |
| 592 | } |
| 593 | #endif |
| 594 | TryNewLink: |
| 595 | client_len = sizeof(atci_client_addr); |
| 596 | int conn = accept(atci_server_socket_fd, |
| 597 | (struct sockaddr *) &atci_client_addr, &client_len); |
| 598 | if (conn <= 0) { |
| 599 | RLOGE("accept error!"); |
| 600 | close(conn); |
| 601 | exit(1); |
| 602 | } |
| 603 | RLOGD("Accept a client , fd is %d", conn); |
| 604 | atci_client_connect = conn; |
| 605 | socketData recv_data; |
| 606 | int ret; |
| 607 | /* tranlate data */ |
| 608 | while (true) { |
| 609 | if (!android::s_registerCalled) { |
| 610 | sleep(1); |
| 611 | continue; |
| 612 | } |
| 613 | #ifdef ATCI_PARSE |
| 614 | memset(parser_buf, 0, sizeof(parser_buf)); |
| 615 | ret = acti_cmd_recv(conn, parser_buf, SOCKET_BUF_SIZE); |
| 616 | if (ret < 0) { |
| 617 | RLOGE("receive CMD error"); |
| 618 | continue; |
| 619 | } else if (ret == SOCKET_ZERO) { |
| 620 | RLOGE("maybe client socket closed 1. retry new link!"); |
| 621 | goto TryNewLink; |
| 622 | } |
| 623 | atci_dispatch_cmd(parser_buf); |
| 624 | #else |
| 625 | memset(parser_buf, 0, sizeof(parser_buf)); |
| 626 | memset(&recv_data, 0, sizeof(socketData)); |
| 627 | |
| 628 | //receive_ID |
| 629 | ret = atci_sock_recv(conn, (char*) &recv_data.requestId, |
| 630 | sizeof(recv_data.requestId)); |
| 631 | if (ret < 0) { |
| 632 | RLOGE("reveive request id is error"); |
| 633 | continue; |
| 634 | } else if (ret == SOCKET_ZERO) { |
| 635 | RLOGE("maybe client socket closed 1. retry new link!"); |
| 636 | goto TryNewLink; |
| 637 | } |
| 638 | RLOGE("reveive request id is %d", recv_data.requestId); |
| 639 | |
| 640 | //receive_length |
| 641 | ret = atci_sock_recv(conn, (char*) &recv_data.datalen, |
| 642 | sizeof(recv_data.datalen)); |
| 643 | if (ret < 0) { |
| 644 | RLOGE("reveive request lenth is error"); |
| 645 | continue; |
| 646 | } else if (ret == SOCKET_ZERO) { |
| 647 | RLOGE("maybe client socket closed 2. retry new link!"); |
| 648 | goto TryNewLink; |
| 649 | } |
| 650 | RLOGE("reveive request lenth is %d", recv_data.datalen); |
| 651 | |
| 652 | //receive_data |
| 653 | recv_data.data = (char*) calloc(recv_data.datalen, 1); |
| 654 | if (NULL == recv_data.data) { |
| 655 | RLOGE("alloc mem error"); |
| 656 | continue; |
| 657 | } |
| 658 | ret = atci_sock_recv(conn, recv_data.data, recv_data.datalen); |
| 659 | if (ret < 0) { |
| 660 | RLOGE("reveive request data is error"); |
| 661 | free(recv_data.data); |
| 662 | recv_data.data = NULL; |
| 663 | continue; |
| 664 | } else if (ret == SOCKET_ZERO) { |
| 665 | RLOGE("maybe client socket closed 3. retry new link!"); |
| 666 | free(recv_data.data); |
| 667 | recv_data.data = NULL; |
| 668 | goto TryNewLink; |
| 669 | } |
| 670 | |
| 671 | int reqNum = ATCIParserRequest(recv_data.requestId); |
| 672 | if (reqNum <= 0) { |
| 673 | RLOGE("ATCI command is error!"); |
| 674 | continue; |
| 675 | } |
| 676 | |
| 677 | int request = MappingATCI2RIL(reqNum); |
| 678 | char reqStr[RIL_REQUEST_STRING_LENGTH]; |
| 679 | |
| 680 | memcpy(reqStr, request2RILStr(request), |
| 681 | strlen(request2RILStr(request)) + 1); |
| 682 | RLOGD("request is %s", reqStr); |
| 683 | argc = MappingParameter(reqNum, recv_data.datalen, recv_data.data, |
| 684 | parser_buf, argv); |
| 685 | if (argc <= 0) { |
| 686 | RLOGE("ATCI command is error!"); |
| 687 | continue; |
| 688 | } |
| 689 | free(recv_data.data); |
| 690 | recv_data.data = NULL; |
| 691 | sendAtciRequest(request, reqStr, argc, argv); |
| 692 | #endif |
| 693 | }; |
| 694 | |
| 695 | RLOGD("close socket fd!"); |
| 696 | close(atci_server_socket_fd); |
| 697 | |
| 698 | RLOGD("exist start ATCI socket thread, errno:%d", errno); |
| 699 | // kill self to restart on error |
| 700 | kill(0, SIGKILL); |
| 701 | return NULL; |
| 702 | } |
| 703 | |
| 704 | #ifdef ATCI_PARSE |
| 705 | char* atci_get_cmd_prefix(char *line) { |
| 706 | int buf_len; |
| 707 | char *prefix; |
| 708 | char *end_ptr; |
| 709 | if (NULL == line) { |
| 710 | RLOGD("input is null"); |
| 711 | return NULL; |
| 712 | } |
| 713 | end_ptr = line; |
| 714 | while (!ATCI_IS_CAHR(*end_ptr, ATCI_EQUAL) |
| 715 | && !ATCI_IS_CAHR(*end_ptr, ATCI_QUESTION_MARK) |
| 716 | && !ATCI_IS_CAHR(*end_ptr, ATCI_END_CHAR) |
| 717 | && !ATCI_IS_CAHR(*end_ptr, ATCI_CR) && !ATCI_IS_CAHR(*end_ptr, ATCI_LF)) { |
| 718 | end_ptr++; |
| 719 | } |
| 720 | buf_len = end_ptr - line + 1; |
| 721 | prefix = (char *) calloc(buf_len, 1); |
| 722 | if (prefix) { |
| 723 | int i; |
| 724 | char *in_ptr = line; |
| 725 | char *out_ptr = prefix; |
| 726 | for (i = 0; i < buf_len - 1; i++) { |
| 727 | if (!ATCI_IS_CAHR(*in_ptr, ATCI_SPACE)) { |
| 728 | *out_ptr = ATCI_UPPER_TO_LOWER(*in_ptr); |
| 729 | out_ptr++; |
| 730 | } |
| 731 | in_ptr++; |
| 732 | } |
| 733 | *out_ptr = ATCI_END_CHAR; |
| 734 | } |
| 735 | RLOGD("get cmd prefix [%d][%s]", buf_len, prefix); |
| 736 | return prefix; |
| 737 | } |
| 738 | |
| 739 | int atci_get_cmd_mode(char *line) { |
| 740 | int reasult = AT_WRONG_MODE; |
| 741 | char *p_cur = NULL; |
| 742 | if (NULL == line) { |
| 743 | reasult = AT_WRONG_MODE; |
| 744 | RLOGD("atci_get_cmd_mode error, input is NULL"); |
| 745 | return reasult; |
| 746 | } |
| 747 | p_cur = strchr(line, ATCI_EQUAL); |
| 748 | if (NULL == p_cur) { |
| 749 | p_cur = strchr(line, ATCI_QUESTION_MARK); |
| 750 | if (NULL == p_cur) { |
| 751 | reasult = AT_ACTIVE_MODE; |
| 752 | } else { |
| 753 | reasult = AT_READ_MODE; |
| 754 | } |
| 755 | } else { |
| 756 | p_cur++; |
| 757 | atci_at_skip_space(&p_cur); |
| 758 | if (ATCI_QUESTION_MARK == *p_cur) { |
| 759 | reasult = AT_TEST_MODE; |
| 760 | } else { |
| 761 | reasult = AT_SET_MODE; |
| 762 | } |
| 763 | } |
| 764 | RLOGD("atci_get_cmd_mode success[%d]", reasult); |
| 765 | return reasult; |
| 766 | } |
| 767 | |
| 768 | int atci_dispatch_cmd(char *line) { |
| 769 | int ret = SYS_FAIL; |
| 770 | char *prefix = NULL; |
| 771 | //atci_Info_t* atci_ptr = atci_info_get(); |
| 772 | atci_cmd_type_t* cmd_handle = NULL; |
| 773 | if (NULL == line) { |
| 774 | RLOGD("CMD is null"); |
| 775 | return SYS_FAIL; |
| 776 | } |
| 777 | RLOGD("enter: %s", line); |
| 778 | |
| 779 | prefix = atci_get_cmd_prefix(line); |
| 780 | if (NULL == prefix) { |
| 781 | RLOGD("atci_cut_cmd_prefix error"); |
| 782 | return SYS_FAIL; |
| 783 | } |
| 784 | RLOGD("find prefix [%s]", prefix); |
| 785 | cmd_handle = atci_find_cmd_handler(prefix); |
| 786 | free(prefix); |
| 787 | if (NULL == cmd_handle) { |
| 788 | RLOGD("not find handler"); |
| 789 | } else { |
| 790 | RLOGD("find handler"); |
| 791 | int cmd_mode = atci_get_cmd_mode(line); |
| 792 | char response[MAX_RESP_BUF_LENGTH]; |
| 793 | memset(response, 0, sizeof(response)); |
| 794 | RLOGD("write to handler"); |
| 795 | ret = cmd_handle->cmd_handle_func(line, cmd_mode, cmd_handle->target, |
| 796 | response); |
| 797 | if (SYS_FAIL == ret) { |
| 798 | RLOGD("cmd_handle_func error"); |
| 799 | } else { |
| 800 | RLOGD("cmd_handle_func success"); |
| 801 | } |
| 802 | } |
| 803 | return ret; |
| 804 | } |
| 805 | #endif |