You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从手机访问SIM卡上的BIP/TCP服务器?

如何从手机访问SIM卡上的BIP/TCP服务器

问题背景

开发JavaCard小程序时,通过BIP在端口12345开启了TCP服务器通道,但Android(需兼容iPhone)端的普通TCP客户端无法建立连接,尝试127.0.0.1、192.169.0.1/2、localuicc均失败,执行ping localuicc提示未知主机,系统路由表也未显示SIM卡相关子网。

JavaCard端实现代码

import static uicc.toolkit.ToolkitConstants.*;
import uicc.toolkit.*;
import javacard.framework.*;

public class NetworkApplet extends Applet implements ToolkitInterface {
    static final short TCP_TX_BUFFER = Byte.MAX_VALUE * 2;
    static final short PORT_SERVER = 12345;
    static final byte IDX_ID_SERVER_CHANNEL = 0;
    byte[] ids;

    @SuppressWarnings("unused")
    public static void install(byte[] bArray, short bOffset, byte bLength) throws SystemException {
        NetworkApplet applet = new NetworkApplet(bArray, bOffset, bLength);
        applet.register();
        applet.setupToolkitRegistry();
    }

    NetworkApplet(byte[] bArray, short bOffset, byte bLength) {
        ids = JCSystem.makeTransientByteArray((short) 2, JCSystem.CLEAR_ON_RESET);
    }

    void setupToolkitRegistry() {
        ToolkitRegistry registry = ToolkitRegistrySystem.getEntry();

        // snip
        registry.setEvent(EVENT_PROFILE_DOWNLOAD);
    }

    @Override
    public void process(APDU apdu) throws ISOException {
        // Unused
    }

    @Override
    public void processToolkit(short event) throws ToolkitException {
        switch (event) {
            case EVENT_PROFILE_DOWNLOAD:
               ids[IDX_ID_SERVER_CHANNEL] = openServerChannel(PORT_SERVER, TCP_TX_BUFFER);
               break;
            // snip
        }
     }

    private static byte openServerChannel(short port, short txCapacity) {
        ProactiveHandler handler = ProactiveHandlerSystem.getTheHandler();
        ProactiveResponseHandler responseHandler = ProactiveResponseHandlerSystem.getTheHandler();

        handler.init(PRO_CMD_OPEN_CHANNEL, (byte) 0, DEV_ID_TERMINAL);
        handler.appendTLV(TAG_BUFFER_SIZE, txCapacity);
        handler.appendTLV(TAG_UICC_TERMINAL_TRANSPORT_LEVEL, QUAL_TCP_SERVER, port);

        if (handler.send() == RES_CMD_PERF) {
            return responseHandler.getChannelIdentifier();
        } else {
            return 0;
        }
    }
}

核心问题分析

  1. BIP并非普通IP网络:SIM卡的BIP通道是终端与UICC之间的专用逻辑通道,不依赖手机的普通IP栈,普通Socket API无法直接访问。
  2. localuicc解析限制:TS 102485规范中localuicc仅针对终端的专用BIP接口生效,普通系统工具(如ping)无法识别,且BIP不支持ICMP协议,因此ping必然失败。
  3. 路由表无相关条目:SIM卡的BIP通道不会暴露在系统路由表中,无需通过IP路由方式访问。

解决方案

Android端实现

Android需使用TelephonyManager的BIP专用API(需系统级权限或运营商签名):

  1. 声明权限:在AndroidManifest.xml中添加:
    <uses-permission android:name="android.permission.MODIFY_PHONE_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    
  2. 连接BIP通道:
    TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
    UiccManager uiccManager = telephonyManager.getUiccManager();
    UiccCard uiccCard = uiccManager.getUiccCardForSlotId(0); // 0为目标SIM卡槽ID
    if (uiccCard != null) {
        UiccApplication app = uiccCard.getApplication(UiccApplication.AppType.AID, "你的小程序AID");
        if (app != null) {
            BiPChannel channel = app.openBiPChannel(BiPChannel.PROTOCOL_TCP, 12345);
            if (channel != null) {
                InputStream in = channel.getInputStream();
                OutputStream out = channel.getOutputStream();
                // 数据交互逻辑
                channel.close();
            }
        }
    }
    
    注:部分设备可能需要运营商定制SDK或系统级权限才能调用BIP接口。

iOS端实现

iOS需使用CoreTelephony框架的专用BIP接口(需苹果开发者账号及运营商权限):

  1. 导入框架:
    import CoreTelephony
    
  2. 连接BIP通道:
    let cellularData = CTCellularData()
    cellularData.cellularDataRestrictionDidUpdateNotifier = { status in
        if status == .notRestricted {
            let uiccManager = CTUICCManager.shared()
            if let uiccCard = uiccManager.uiccCards?.first {
                if let app = uiccCard.applications?.first(where: { $0.aid == "你的小程序AID" }) {
                    app.openBiPChannel(protocol: .tcp, port: 12345) { channel, error in
                        if let channel = channel {
                            let inputStream = channel.inputStream
                            let outputStream = channel.outputStream
                            // 数据交互逻辑
                            channel.close()
                        }
                    }
                }
            }
        }
    }
    
    注:iOS的BIP接口仅对合作方开放,需联系苹果及运营商获取权限。

JavaCard端补充优化

  1. 校验通道开启状态:在openServerChannel中确保RES_CMD_PERF返回值正确,确认通道ID有效。
  2. 监听数据事件:添加EVENT_DATA_AVAILABLE事件监听,处理终端发送的数据:
    @Override
    public void processToolkit(short event) throws ToolkitException {
        switch (event) {
            case EVENT_PROFILE_DOWNLOAD:
                ids[IDX_ID_SERVER_CHANNEL] = openServerChannel(PORT_SERVER, TCP_TX_BUFFER);
                break;
            case EVENT_DATA_AVAILABLE:
                ProactiveHandler handler = ProactiveHandlerSystem.getTheHandler();
                byte channelId = handler.getChannelIdentifier();
                if (channelId == ids[IDX_ID_SERVER_CHANNEL]) {
                    byte[] buffer = new byte[TCP_TX_BUFFER];
                    short len = handler.copyValue(buffer, (short)0);
                    // 数据处理逻辑
                }
                break;
            // snip
        }
    }
    

内容的提问来源于stack exchange,提问作者Typhaon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 01:21:02