En 2003, el teléfono móvil TSM30 de Vitelcom llegó al mercado - un móvil con muchas características desarrollado por una empresa española a un precio muy razonable. Antes del TSM30, se había lanzado el TSM100, un teléfono similar pero con una pantalla táctil resistiva.
Estos teléfonos móviles crearon una comunidad de usuarios en España y ocurrieron cosas muy interesantes. Pero lo que sin duda hace especial a este móvil es que fue la primera vez que se filtró la pila GSM, así como el código de un DSP (TI Calypso). Esta filtración se atribuye al grupo ?Hispaphreak, que publicó todo el código fuente en el portal de proyectos libres (entonces famoso) Sourceforge. Dado que nadie se dio cuenta durante tantos años, el código inmediatamente pasó a considerarse DOMINIO PÚBLICO.
Gracias a esta contribución de este grupo de hackers españoles, surgieron proyectos como OpenBSC, OpenBTS, OsmocomBB…
Características del Terminal TSM30 205
Sistema
- Sistema Operativo: Propietario
- Almacenamiento: 2 MB
- Tarjeta: MMC/SD
- J2ME: SÍ
Pantalla
- 160x128 píxeles, 65k colores
Cámara
- 0.3MP (640x480 Píxeles)
Otros Datos
- Calendario: SÍ
- Vibración: SÍ
- Radio: NO
- Observaciones: I-Mode, SD/MMC
- SAR: 0.95 W/kg (cabeza)
Redes
- Banda: 2G: GSM 1800, GSM 900, GSM 1900
- GPRS: SÍ
Batería
- Autonomía (Llamada): 2.3 h (GSM)
- Autonomía (Espera): 180 h (GSM)
- Batería: Li-Ion
- Removible: SÍ
Apariencia
- Dimensiones: 113x48x21 mm
- Peso: 110 gr
- SIM: SIM
Comunicaciones
- Bluetooth: NO
- NFC: NO
- IrDA: SÍ
- USB: SÍ
- WiFi: NO
- GPS: NO
- Mensajes: SMS/EMS/MMS
Entorno de Desarrollo
El código del firmware está completamente escrito en C. Para compilarlo desde las fuentes, que están disponibles en Internet, necesitaremos instalar algunas utilidades de Texas Instruments, o descargar el entorno de desarrollo que solo funciona en sistemas compatibles con NT (Windows NT, 2000, XP, 2003).
Dentro del archivo zip, encontraremos no solo la fuente del firmware, sino también los compiladores necesarios (TEXAS INSTRUMENTS) para construir el firmware.
El código está muy bien organizado y documentado. Podemos encontrar diferentes directorios clasificados. Quiero destacar que en el proyecto, los objetos se compilan tanto para la MCU (Unidad de MicroControlador) como para el DSP (Procesador de Señal Digital). Como puedes imaginar, el sistema operativo se ejecuta en la MCU y la banda base en el DSP.
Para montar las unidades con los compiladores, ejecutaremos el archivo mount.bat. Esto montará 3 unidades:
- R:
- S:
- W:
Encontraremos un archivo llamado Official.zip, que contiene el código fuente real. Necesitaremos descomprimirlo (asegurándonos de que las propiedades no sean de solo lectura) y montarlo como V: de esta manera:
subst V: Official
Para compilar el firmware, solo necesitamos ir a V:\Common\INTEGRATION\bin
y ejecutar dmakeall.bat
Definiciones de Prototipos Internos
#if (MODULE_NUMBER == MODULE_PKRN)
Comunicaciones
Las rutinas de comunicación GSM están en los directorios MCU\Layer1 y MCU\Protocol con algunas definiciones en MCU\inc\cdg
Las estructuras de flujo se pueden encontrar en spy_decoding.ini
Por ejemplo, podemos ver que soporta estos valores para “Elemento de información del indicador de progreso”:
LOC_USER 0x0 /* usuario */
LOC_PRIV_NET_LOCAL_USER 0x1 /* red privada que sirve al usuario local */
LOC_PUB_NET_LOCAL_USER 0x2 /* red pública que sirve al usuario local */
LOC_TRANSIT_NET 0x3 /* red de tránsito */
LOC_PUB_NET_REMOTE_USER 0x4 /* red pública que sirve al usuario remoto */
LOC_PRIV_NET_REMOTE_USER 0x5 /* red privada que sirve al usuario remoto */
LOC_INTERNATIONAL_NET 0x7 /* red internacional */
LOC_BEYOND_POINT 0xA /* red más allá del punto de interconexión */
LOC_GNOLZ_1 0x1 /* reservado */
Lo que significa que acepta el valor 0x3, y lo tratará con el significado de “red de tránsito”, aunque más tarde el programa en MCU\Protocol\CC\Src\CC_FFK.C lo maneja como si fuera lo mismo que LOC_PUB_NET_LOCAL_USER. Transforma LOC_TRANSIT_NET en LOC_USER.
Hola Mundo
Bueno, ahora que nos hemos familiarizado con el entorno de desarrollo móvil, hagamos algo de práctica… y… ¿qué mejor que “Hola Mundo”?
Nos moveremos al directorio V:\MCU\Presentation\Idle\Src
y abriremos pidl04debug.hv
que contiene definiciones de utilidades de depuración. Aquí podemos capturar un código ingresado por teclado y lanzar la aplicación que queremos (nuestro “Hola Mundo”)… y bueno, ya que eres muy l33t y hax0rs… pondremos “##31337” como el código de acceso a nuestra aplicación.
typedef struct {
char * p_KeySeq;
t_pidl_KeyFunction * p_Func;
} st_pidl_KeyTable;
GLOBAL_EXT const st_pidl_KeyTable tabla[]
= {
"##31337", pidl04_nuestra_funcion,
/*
...
...
...
*/
NIL, pidl04_06UnknownSeq
};
Ahora vamos a crear nuestra función añadiendo las siguientes líneas a pidl04debug.c
:
u8 pidl04_nuestra_funcion(char *pp_String)
{
pcom02_11SimpleTimedBox((u8 *)"Hola Mundo", (u8 *)"l33t Msg", PPMT_EOL_DUMMY_PROMPT_SPT2, PPMT_EOL_DUMMY_PROMPT_SPT2, 0 );
return (TRUE);
}
Las interfaces de usuario para confirmación están definidas en V:\MCU\Presentation\Common\Src\pcom02cfirm.c
:
void pcom02_01EasySettingMessageBox( st_MsgBoxPZ *pl_MsgBox );
u16 pcom02_09SimpleMsgBox( u8* p_Text, u8* p_Title, t_PromptId v_Text, t_PromptId v_Title, u32 v_Flags );
u16 pcom02_10SimpleBox( u8* p_Text, u8* p_Title, t_PromptId v_Text, t_PromptId v_Title, u32 v_Clear );
u16 pcom02_11SimpleTimedBox( u8* p_Text, u8* p_Title, t_PromptId v_Text, t_PromptId v_Title, u32 v_Clear );
u16 pcom02_12SimpleYesNoBox( u8* p_Text, u8* p_Title, t_PromptId v_Text, t_PromptId v_Title, u32 v_Clear );
u16 pcom02_13SimpleInfoBox( u8* p_Text, u8* p_Title, t_PromptId v_Text, t_PromptId v_Title, u32 v_Clear );
u16 pcom02_14SimpleWarningBox( u8* p_Text, u8* p_Title, t_PromptId v_Text, t_PromptId v_Title, u32 v_Clear );
u16 pcom02_15SimpleYesNoCancelBox( u8* p_Text, u8* p_Title, t_PromptId v_Text, t_PromptId v_Title, u32 v_Clear );
u16 pcom02_16SpecialTimedBox( u8* p_Text, u8* p_Title, t_PromptId v_Text, t_PromptId v_Title, u32 v_Clear, u8 vp_DisplayAttributes );
u16 pcom02_17SimpleGoPostponeDeleteBox( u8* p_Text, u8* p_Title, t_PromptId v_Text, t_PromptId v_Title, u32 v_Clear );
u16 pcom02_18SimpleSilentBox( u8* p_Text, u8* p_Title, t_PromptId v_Text, t_PromptId v_Title, u32 v_Clear );
u16 pcom02_19SimpleSilentTimedBox( u8* p_Text, u8* p_Title, t_PromptId v_Text, t_PromptId v_Title, u32 v_Flags ) ;
u16 pcom02_20SimpleBoxGo( u8* p_Text, u8* p_Title, t_PromptId v_Text, t_PromptId v_Title, u32 v_Flags, st_MsgBoxPZ *pl_MsgBox );
u16 pcom02_23SimpleIconTimedBox ( u8* p_Text, u8* p_Title, t_PromptId v_Text, t_PromptId v_Title, t_IconId v_Icon, u32 v_Flags );
u16 pcom02_24SimpleBoxWarm( u8* p_Text, u8* p_Title, t_PromptId v_Text, t_PromptId v_Title, u32 v_Flags );
u16 pcom02_26ExitAndDiscardNotif( void );
u16 pcom02_27DeleteConfirmation( void );
u16 pcom02_99MsgBoxTest( u8* p_Text, u8* p_Title, u8* p_But );
u16 pcom02_25OneButton( u8* p_Text, u8* p_Title, t_PromptId v_Text, t_PromptId v_Title, u32 v_Flags );
u16 pcom02_26ExitAndDiscardNotif(void);
u16 pcom02_27DeleteConfirmation(void);
u16 pcom02_28DeleteAllConfirmation(void);
u16 pcom02_29PleasePowerCycle(void);
u16 pcom02_30FileSystemFull(void);
u16 pcom02_31MemoryCheckAndNotify(u8 * pp_Level, u8 * pp_Percentage);
Si queremos trabajar con búferes que el usuario copia y quiere pegar, utilizaremos las siguientes funciones:
_globext_ u8 pcom03_01Copy ( t_BufferType vp_BufferType, void *vp_Data, u16 vp_Size );
_globext_ t_BufferType pcom03_02Paste ( void **pp_DataPtr, u16 *pp_SizePtr );
_globext_ void pcom03_03InitialiseClipboard ( void );
_globext_ t_BufferType pcom03_04IsBufferData ( void );
_globext_ u8 pcom03_05IsBufferLocked ( void );
_globext_ void pcom03_06LockBuffer ( void );
_globext_ void pcom03_07UnlockBuffer ( void );
_globext_ u8 pcom03_08CanCopy ( u8 a, u16 b, st_HandlerControlBlock *c );
_globext_ void pcom03_09LaunchTimeoutTimer ( t_TimeoutContext ) ;
_globext_ void pcom03_10StopTimeoutTimer ( t_TimeoutContext ) ;
Introducción a GSM/GPRS/I-MODE
Cada vez que encendemos un teléfono móvil, se nos presenta una invitación (CHV1) en la pantalla para ingresar el PIN1 que nos permitirá acceder a la red GSM. Este Número de Identificación Personal no necesita la red de telefonía móvil, pero su validación se realiza por la propia tarjeta SIM.
Para hacer otras cosas como cambiar opciones una vez que estamos conectados a la red (CHV2), necesitaremos usar el PIN2, pero no es necesario conocerlo para el uso normal en la red.
El proceso de acceso a la red se inicia por el móvil una vez que el usuario ha ingresado correctamente el PIN; en ese momento, el móvil recibe el RAND de la red, que es un número aleatorio (RANDOM) que utiliza junto con el Ki para generar las claves SRES y Kc.
El Ki (Clave Interna) es un número almacenado en la SIM al que no se puede acceder directamente desde el terminal móvil, sin embargo, los operadores tienen una base de datos con los Ki en el AC (Centro de Autenticación).
El SRES (Resultado) se devuelve a la red para completar el sistema de autenticación y se genera con el Ki y el RAND.
El Kc (clave de cifrado) se genera con el algoritmo A3, y nos servirá como clave para cifrar las comunicaciones cuando la red tenga la encriptación activa. Al igual que el SRES, el Kc se genera con el Ki y el RAND. El 11M, muchos teléfonos móviles de la compañía MoviStar advirtieron que no se estaba utilizando ningún tipo de encriptación por razones que todos podemos imaginar.
El IMSI (Número de Identificación del Suscriptor Móvil) es un número que nos identifica a nivel mundial como suscriptores de la red de un operador de telefonía móvil. Consiste en MCC, MNC y MSIN.
MCC (código de país móvil) es el identificador de la red de un país y consta de 3 dígitos. MNC (código de red móvil) es el identificador de la red de un operador, formado por 2 dígitos. MSIN (número de identificación del suscriptor móvil) es el número de identificación del suscriptor (no tiene que coincidir con el MSISDN, es decir, el número de teléfono del suscriptor que la red nos asigna cuando ha verificado los datos), y se reservan 10 dígitos para él.
La mayoría de los teléfonos móviles miran los primeros 3 dígitos del IMSI (que indican el país) para mostrar menús en un idioma u otro.
El TMSI es el tiempo que una actualización de ubicación debe ejecutar para informar a la red de la disponibilidad de nuestro terminal móvil.