View this PageEdit this PageUploads to this PageVersions of this PageHomeRecent ChangesSearchHelp Guide

Desarrollando para Symbian

classes/structs/h/bb

CONE classes/minimal

Symbian OS C++ Reference (S60 5th)
Por componentes: EKA2 Comms
Symbian Developer Network KB (live.sdnhost.com)
Doxygen local de epoc32 (symbian)
Symbian error codes
Symbian OS source code
NOTA: Voy por aquí en tutoriales.



Monday, 14 January 2013, 6:53:56 pm
Otra manera de obtener la MAC No hace falta el tener abierta la conexión, basta seguir los pasos del interfaceListing() deprecado de http://www.qt.gitorious.org/qt/qtbase/commit/4329030b77dc2faf267cecc0a8b03ce3ed3437cf?format=patch. Básicamente es:
  1. Inicializar un RSocket del socket server
  2. Inicializar
    TPckgBuf infoPckg;
    TSoInetInterfaceInfo &info = infoPckg();
  3. Obtener los interfaces con GetOpt(KSoInetNextInterface, KSolInetIfCtrl, infoPckg)
  4. Si "info.iHwAddr.Family() != KAFUnspec", entonces está en "info.iHwAddr[0..5]"

Friday, 11 January 2013, 6:39:14 pm
A vueltas con SIOCIFSTART Para el TCM 1.1.2 he vuelto a poner las conexiones usando OpenC, esta vez protegiéndolas con un select. Resulta que la llamada ioctl de SIOCIFSTART tarda 2s (!!!), el SIOCSIFNAME es muy rápido (aunque no instantáneo).
Hay documentación de su uso aquí:
Para obtener la MAC desde OpenC, debería funcionar el siguiente procedimiento (por fin una manera ¡yay!):
if(ioctl(fd, SIOCGIFHWADDR,&(APs[i].ifr))==0) {
    unsigned char *ptr;
    char mac_address[6*2+5+1];
    ptr=(unsigned char *) (APs[i].ifr.ifr_hwaddr.sa_data);
    sprintf(mac_address,"%02x:%02x:%02x:%02x:%02x:%02x",
    ptr[0],ptr[1],ptr[2],ptr[3],ptr[4],ptr[5]);
    MacInit(mac_address);
}

Aún así, este patch de las Qt debería dar alguna idea (ya que usa en Linux el SIOCGIFHWADDR, y en symbian/OpenC alguna otra cosa, hay que mirar qué otra cosa).

Tuesday, 3 July 2012, 4:34:06 pm
Se ha comprado el nuevo certificado para 2012_2013 Y ya se han realizado los pasos indicados en "Wednesday, 6 July 2011, 6:40:12 pm" para verificar la cuenta en symbian signed con el nuevo certificado.

Wednesday, 6 July 2011, 6:40:12 pm
Cuando caduca el certificado de trustcenter (el PublisherId, vamos) Hay que comprar uno nuevo en trustcenter.de (usando los mismos detalles que en la anterior compra, y una vez que responden, mandando por fax la primera hoja firmada del pdf adjunto en su mail, junto con el certificado de la SS de que estamos al corriente de pago y fotocopia del DNI de la persona que lo solicita (Darío)). Con todo eso terminan mandando un nuevo email con un enlace en el que descargas el certificado (la última vez lo hemos hecho todo desde el IE9 del W7 de Javi). Por último hay que exportar el pfx desde el IE a un archivo y se pone en dario@phonedevel:~ ; en este caso el archivo le hemos llamado: SymbianSicosoft2011_2012.pfx. En phonedevel hay que realizar los siguientes pasos:
 ./pfx2cer_key.sh SymbianSicosoft2011_2012.pfx passworddelpfx
Después se entra en symbiansigned, se da a "verify account" y se descarga el sis de prueba. Con ese .sis se hace lo siguiente:
 cd Descargas
 . ~/gnupoc/env.sh 2>/dev/null >/dev/null
signsis symbian_signed_account_verification_sis.sis symbian_signed_account_verification_sis.sisx ../SymbianSicosoft2011_2012.pfx.cer ../SymbianSicosoft2011_2012.pfx.key
 mv symbian_signed_account_verification_sis.sisx symbian_signed_account_verification_sis.sis
Y el .sis resultante lo subes a la página de verificación de la cuenta.
Por último borras el .sis que ya no sirve para nada más:
 rm symbian_signed_account_verification_sis.sis

Wednesday, 18 May 2011, 5:33:13 pm
Sobre el libro Qt for symbian La web del libro, ¿contenido?, ¿pdf?.

Wednesday, 18 May 2011, 5:27:50 pm
No es symbian propiamente dicho, pero era por escribirlo en alguna parte: Qt en S40 En este post del 28/05/2009 se menciona lo siguiente:

This Qt for S40 issue is likely to go one of two ways. Either Qt will be supported on S40, or S40 will be phased out before that happens (i.e. if Nokia can't leverage their cross-platform effort on S40 then it will not make sense to use S40 much any more, probably only for the very low end devices where price is really the only thing that matters). I think the former is much more likely than the latter. Then the question will be whether or not Qt is open to 3rd party developers on S40 (there are issues with opening a native runtime on a simple RTOS).

At NDS in Monaco, Mika Rytkonen was asked this question about Qt on S40, he said a feasibility study was in progress and the results were looking pretty good so far. That's about as much encouragement/info as you can get for now.



Tuesday, 29 March 2011, 10:59:57 am
Nokia free signing Sobre todo es interesante para aplicaciones J2ME.: http://www.forum.nokia.com/Distribute/Packaging_and_signing.xhtml

Friday, 25 February 2011, 10:09:26 am
Poniendo una MessegeBox/InfoWin cuando la aplicación está en segundo plano: Global note Aquí explica como poner un global note, que es un infobox con su propia ventana, con lo que sale aunque la aplicación esté en segundo plano.

Friday, 25 February 2011, 9:58:36 am
Detectando el offline mode y aceptando de forma automática el prompt Para detectarlo hay dos maneras, la fácil en S60 3rd FP1 y la difícil en S60 3rd.

Tuesday, 22 February 2011, 12:25:38 pm
Capturas de pantalla Las capturas de pantalla se hacen usando el e60 con el programa screenshot. Usa EDIT+'*' para hacer las capturas. Una vez que hayas terminado de hacerlas, puedes usar la siguiente script para traértelas por bluetooth:

 dario@symbiandevel:~/workspace/screenshots$ ./e60_get_screenshots.sh

Friday, 28 January 2011, 11:59:39 am
Portado de la aplicación a S^3 táctil y uso de "s60 screen widgets" Buscando alternativas, resulta que los terminales symbian siguen siendo los mas adecuados, ya que son los únicos con un buen soporte VoIP (SIP), WiFI y alta programabilidad (aunque el Symbian C++ sea un desastre).

Para compensar el que no tengan keypad físico para poder abrir los portones, la alternativa es poner botones específicos para abrir los portones usando "s60 screen widgets (se hacen usando el Web RunTime, WRT; espero que sean capaces de comunicar con una aplicación que funciona en segundo plano...).

Friday, 29 October 2010, 11:21:41 am
Port a Qt4.7+Qt Mobility 1.0 La parte relevante de Qt mobility es: bearer management para la elección del punto de acceso y system information para obtener el imei y la mac. Me falta encontrar la manera de "capturar" botones system-wide.

Friday, 30 July 2010, 6:41:35 pm
Backtraces en Symbian Para lospanic de ALLOC, hay una utilidad que se usa con el simulador HookLogger.

También hay un página con las debugging techniques.

Thursday, 29 July 2010, 6:52:23 pm
Parece que hay que usar a la vez el CaptureKey y el CaptureKeyUpAndDowns Según este post así sí que consigue "consumir" la tecla.

Más sobre teclas En este thread dan un enlace a esta lista de tips para Symbian y en concreto Symbian Programming - Capturing key presses in thread/exe, que dicen que no funciona para capturar las del keypad (0-9) porque ya las captura el dialer... pero como bonus indican cómo hacer que la aplicación no aparezca en la lista de tareas del "task switcher" (necesrio si se quiere hacer lo del icono indicando TCM activo).

Thursday, 22 July 2010, 10:49:04 am
Corrección importante en 1.0.2alpha3 (parseado de subsistemas) En 1.0.2alpha3 corrijo que si vienen más de 1024 bytes de subsistemlist (también en los otros módulos, pero el bug se veía aquí), no se ponían todos los subsistemas.

Thursday, 8 July 2010, 12:47:13 pm
Para el SELDAM (bueno, es del tctiserver y no del teléfono, pero por apuntarlo en algún sitio) Con InfoGlobal vamos a hablar con SOAP. Librería en C con licencia LGPL para SOAP (manual en línea: indice/contenido).

Wednesday, 30 June 2010, 4:42:38 pm
Cosas de symbian... Ayer areglé dos "bugs" (uno sí lo era, pero el otro...).
  1. En los timeouts de TCMSocket.cpp se estaba modificando iStatus (la variable de estado del active object) en vez de iState (no tiene por qué tener este nombre; mantiene el estado de la máquina de estados de esta instancia del active object), provocando un PANIC. Eso de mantener dos estados y que el del active object no haga referencia a los active objects es un engorro.
  2. Resulta que si llamas a SetActive() cuando el objecto ya está activo, obtienes un panic. ¿La solución recomendada? Pues preguntarte antes de llamarlo si "IsActive()" y todo arreglado.
Y esto es después de que la semana pasada arreglase otro "bug" que realmente también es una idiosincrasia de Symbian C++:
  • Al parecer, no se puede reactivar un objeto dentro de un CActiveSchedulerWait (un bucle de eventos anidado) llamado desde una función que ha sido llamada desde el RunL(). No se me ocurre la razón, pero el mismo código sin estar en el bucle de eventos anidado sí funciona.

Tuesday, 29 June 2010, 7:36:33 pm
Otro ejemplo de sockets De esta thread, este ejemplo: sntpclientengine.cpp

Tuesday, 22 June 2010, 5:54:32 pm
MagicKey Para averigual el scancode de un botón se hace con el MagicKey (tutorial). Básicamente:
1. Se abre el MagicKey
2. Le das a flechita derecha para ir a keymaps
3. Vas a opciones y le dices "Add" nuevo keymap
4. Le das un nombre diferente (p.ej. flechita derecha y "2")
5. Le das a Edit
6. Le das a "Add key pair"
7. CUando estás encima del de entrybox de arria, le das a la tecla de descolgar (aparecerá un "999") y después a la tecla de la que quieres investigar el keycode; te aparecerá el keycode a usar para esa tecla :-).

Tuesday, 1 June 2010, 6:06:12 pm
Ejemplo de servidor en S60: un ftp server Symbian FTp Server for S60 3rd, sources. Para obtener los fuentes basta hacer un:
$ mkdir src.dftpd
$ cd src.dftpd
$ git clone git://repo.or.cz/dftpd.git

Update: No parece aportar nada; está hecho en Open C/C++ y no veo ninuna llamada para hacer que el teléfono esté "siempre listo" para recibir connects.

Tuesday, 1 June 2010, 5:29:57 pm
A vueltas con el Listen: CommDD capability Haciendo pruebas, si activo el CommDD capability sí que me puedo conectar al teléfono, pero sólo durante un pequeño lapso de tiempo después de que haya hecho él una conexión (antes ni eso).

NOTA: CommDD es un "Manufacturer capability" según el "dg_signing_symbian_r2a.pdf" de UIQ3. Corto y pego:

Manufactuer Capabilties (Channel Certification: Signed Symbian + manufacturer independant tests)
· DRM
· NetworkControl
· MultimediaDD
· TCB
· AllFiles
· CommDD
· DiskAdmin

CommDD
Grants access to all communication device drivers, for example EComm and USB device drivers.
API examples: COMMS


Update: Basta con el ReadDeviceData, que al menos no es una "manufacturer capability", tan sólo una "extended capability".
Extended capabilities
ReadDeviceData
Grants read access to confidential system data. System data that is not confidential does not need to be protected by this capability.
API examples: COMM


Thursday, 27 May 2010, 6:40:06 pm
El capítulo de sockets del tutorial "Fundamentals of Symbian C++" Sockets (Fundamentals of Symbian C++)

Monday, 24 May 2010, 7:00:01 pm
Ejemplo funcional de server sockets Está aquí.

Thursday, 13 May 2010, 6:36:29 pm
Ahora que ya funcionan los sockets symbian: hacer un textinput Ya funcionan los sockets symbian (uf, eso ha costado), y la aplicación es estable y funciona en todas las estaciones. Lo siguiente es implementar el que haya varios servidores de autentificación configurados, el poder recibir una lista de servidores de autentificación a usar y el añadir al menú oculto un textinput ("Data query" en "symbianspeak") para añadir IPs de servidores de autentificación. Ver pg. 67 de:
 salchicha:/home/dario/Programacion/doc/s60/S60_UI_Style_Guide_v1_2_en.pdf

También falta el añadir al menú oculto (o al normal... no está claro todavía) que se pueda elegir el plano al que conectarse de todos los planos que se hayan recibido del servidor de autentificación.

Tamién falta el implementar que funcionen los sockets entrantes para poder mandar las alarmas urgentes.

Tuesday, 4 May 2010, 5:06 pm
La Stack Intentando depurar un "KERN-EXEC 3", me he encontrado con este thread. Resulta que para aumentar el tamaño del stach desde los 8kB por defecto a 80kB (es el máximo), basta con añadir al .mmp la siguiente línea:
EPOCSTACKSIZE 0x14000

NOTA: Al final el "KERN-EXEC 3" era debido a que se usaba iSocket antes de haberlo "rellenado". Por alguna razón, ListenInitialized() era llamado antes de termina el ConstructL de TCMAppUi. Moviendo la inicialización de iSocket a antes de la inicialización de iServerSocketEngine ha quedado todo solucionado :-).

Tuesday, 4 May 2010, 4:57:43 pm
Hecho que ponga mensajes extendidos cuando se cierra la aplicación Siguiendo esta guia. Básicamente:
  • Añadir la siguiente línea a sis/TCM_S60.pkg
"ErrRd"                 -"!:\resource\ErrRd"
  • Generar el fichero ErrRd para que lo encuentre
touch sis/ErrRd

Y con eso, recompilando/reinstalando la aplicación, da mensajes extendidos en los PANICs.


Wednesday, 21 April 2010, 5:28:02 pm
Putty para Symbian S60 3a ed Está aquí (página del proyecto). Está "self-signed"; habría que firmarlo nosotros...

Friday, 16 April 2010, 7:13:32 pm
Añadir un icono en la parte superior de la pantalla de S60 ("universal indicator") Resulta que no hay un API para ello, pero se puede hacer por medio de escritura directa a apantalla usando este tutorial: How to draw an Icon on the IndicatorPane of Series 60 (Adevertencia: ese código se escribió y probó en S60 2nd ed., no en 3rd ed.). Búsqueda relacionada

Wednesday, 14 April 2010, 6:25:59 pm
Y Por fin también, un ejemplo claro de cómo implementar un "Active Object" Según el Ejemplo de GetIMEI, que es corto, hace sólo lo que se le pide y muy, muy claro, se ve lo siguiente:

  • Todos los objetos incluyen su propia factoría, que se llama NewL() (o NewLC(), pero ya no me acuerdo de la diferencia). Dentro de la factoría se inicializa el objeto usando una función miembro que llamaremos (por convención) ConstructL():
CGetIMEI*
CGetIMEI::NewL(/*TDes& aIMEI*/)
{
        CGetIMEI* self = new (ELeave) CGetIMEI(/*aIMEI*/);
        CleanupStack::PushL(self);
        self->ConstructL();
        CleanupStack::Pop(self);

        return self;
}

  • Los objetos NUNCA se generan como autovariables, sino la autovariable es un puntero y se rellena con un objeto que te devuelve la factoría; ese objeto generado así sí que está listo para su uso:
        CGetIMEI* getIMEI = CGetIMEI::NewL();
        TBuf16<30>imei;
        imei.Copy(getIMEI->GetIMEI());

  • En el ConstructL() se inicializan los objetos que pueden "abandonar" (generar un Leave, que es la excepción de symbian; antiguamente usaban setlongjmp()/longjmp(), pero ahora usan excepciones):
void
CGetIMEI::ConstructL()
{
        iTelephony = CTelephony::NewL();
        CActiveScheduler::Add(this); // Add to scheduler
}

  • En el constructor C++ del objeto sólo se inicializan cosas que no generan un Leave:
CGetIMEI::CGetIMEI() : CActive(EPriorityHigh) // HIGH priority
/*,iIMEI(aIMEI)*/
{
        iIMEI.Zero();
        iState = EStart;
}

  • En el destructor hay que llamar el Cancel(), que a su vez llamará a nuestra implementación de DoCancel() si es que el objeto estaba esperando una notificación; también hay que destruir los objetos que hayamos creado en el ConstructL():
CGetIMEI::~CGetIMEI()
{
        Cancel(); // Cancel any request, if outstanding
        // Delete instance variables if any
        delete iTelephony;
}

  • En el DoCancel() hay que llamar al cancel del objeto sobre el que estabamos esperando la notificación:
void
CGetIMEI::DoCancel()
{
        iTelephony->CancelAsync(CTelephony::EGetPhoneIdCancel);
}

  • Hay que definir una función para "activar" el objeto; se puede llamar DoRunL(), StartL(), Open(), Connect()... En él se hace la llamada al sistema que es asíncrona pasándole nuestro iStatus (que tenemos por se herederos de CActive) y notificamos al "Active Scheduler" que estamos esperando una notificación con SetActive(), así como entrar de forma anidada en el bucle de eventos del "Active Scheduler" con iActiveSchedulerWait.Start():
void
CGetIMEI::StartL()
{
        Cancel(); // Cancel any request, just to be sure
        iState = EGetPhoneInfo;
        CTelephony::TPhoneIdV1Pckg phoneIdPckg( iPhoneId );
        iTelephony->GetPhoneId(iStatus, phoneIdPckg);
        SetActive(); // Tell scheduler a request is active
        iActiveSchedulerWait.Start();
}

  • Por último se implementa el RunL(); y si se usa iActiveSchedulerWait, hay que pararlo.
void CGetIMEI::RunL()
{
        iState = EDone;
        if ( iActiveSchedulerWait.IsStarted() ) {
                iActiveSchedulerWait.AsyncStop();
                if(iStatus == KErrNone) {
                        iIMEI.Append(iPhoneId.iSerialNumber);
                        //iAppUi->iIMEI.Append(iPhoneId.iSerialNumber);
                } else {
                        TBuf<64> buf;
                        buf.Num(iStatus.Int());
                        _LIT(KE,"Get Phone Info error:");
                        CEikonEnv::Static()->InfoWinL(KE(),buf);
                }
        }
}

  • En el ejemplo se muestra también cómo hacer una función de conveniencia que inicia el proceso y devuelve el valor-resultado de la llamada al sistema de forma síncrona (en este caso es síncrono gracias a haber usado CActiveSchedulerWait; sin eso sería completamente asíncrono y habría que hacerlo en dos fases, la de instalar la petición y la de capturar la respuesta en el RunL de la clase que llama a instalar la petición):
const TPtrC
CGetIMEI::GetIMEI()
{
        StartL();
        TPtrC ptr(iIMEI.Ptr());
        return ptr;
}

  • Hay que tener cuidado de no confundir "iState" (el nombre que se suele dar al estado de nuestro objeto, que es un TInt normalnte) con "iStatus" (el TRequestStatus que hemos heredado de CActive y que se usa para las notificaciones). Para evitar esto pueder usar otro nombre de variable para el estado del objeto, pero el código que verás por ahí utiliza mayoritariamente "iState".
  • Por completitud, pongo a continuación la definición de la clase:
class CGetIMEI : public CActive
{
        public:
                static CGetIMEI* NewL(/*TDes& aIMEI*/);

                // Cancel and destroy
                ~CGetIMEI();

        public: // New functions
                // Function for making the initial request
                void StartL();

                const TPtrC GetIMEI();

        private:
                // C++ constructor
                CGetIMEI(/*TDes& aIMEI*/);
                // Second-phase constructor
                void ConstructL();

                // From CActive
                // Handle completion
                void RunL();

                // How to cancel me
                void DoCancel();

                // Override to handle leaves from RunL(). Default implementation causes
                // the active scheduler to panic.
                //void RunError(TInt aError);

        private:
                enum TGetIMEIState {
                        EStart = 1,
                        EGetPhoneInfo,
                        EDone
                };

        private:
                TInt iState; // State of the active object
                CTelephony* iTelephony;
                CTelephony::TPhoneIdV1 iPhoneId;
                CActiveSchedulerWait iActiveSchedulerWait;
                TBuf<CTelephony::KPhoneSerialNumberSize> iIMEI;
                //CMobile7AppUi* iAppUi;
};


Y eso es todo. Esta vez, incluso tiene sentido lo de los "Active Schedulers"...

Wednesday, 14 April 2010, 6:06:29 pm
Por fin, una explicación razonable a qué es un "active scheduler"; resulta ser un bucle de eventos Según Common mis-use and abuse of Symbian OS, sobre los active scheduler:
  • Un "Active Scheduler" es un bucle de eventos (equivalente al XtAppMainLoop() de Motif o al GMainLoop de glib).
  • Las aplicaciones gráficas usan el active scheduler que ha creado el interfaz gráfico; heredan de "public CActive", en el constructor lo inicializan con ": CActive(CActive::EPriorityStandard)" y en el cuerpo del constructor hacen un "CActiveScheduler::Add(this);".
  • Las instancias de objetos que quieren poder recibir llamadas desde el "Active Scheduler" lo hacen de un modo priimitivo (parecido al de win16); el "Active Scheduler" llama a la función RunL de dicha instancia cuando tiene algo que notificar. Sin embargo, no informa sobre qué es lo que está notificando (!!!). El objeto ha de saber qué cosa estaba esperando...
  • El "TRequestStatus & aStatus" que hay de parámetro en las funciones asíncronas que dependen del "Active Scheduler" para notificar su finalización, hay dos posibilidades de rellenarlo:
    • Con el iStatus del objeto que desea recibir la notificación (iStatus es un miembro de la clase "CActive", por lo que el objeto ha de heredar de dicha clase para tneerlo)
    • Usando un TRequestStatus "cocinado" y después entrando en el bucle de eventos de una manera especial para esperar que se llame a ese TRequestStatus "cocinado":
                TRequestStatus status(KErrNone);
                iConn.Start(connPref,status);
                User::WaitForRequest(status);



Wednesday, 14 April 2010, 4:42:11 pm
Capturar una tecla En los fuentes del screenshot, eso está en src/BencoolenAppui.cpp:...::DoSetCaptureKey() y las diferentes que han probado en el screenshot están en ...::SetCaptureKey().

Ahora falta por probar que se pueda capturar una tecla del estilo de "shift+1", "shift+2"... para asociarlas a abrir el portón correspondiente.

Hay un post con las scancodes de las teclas de un n73:
KeyScancode
*42
#127
Number 0 48
Number 1 49
Number 2 50
Number 3 51
Number 4 52
Number 5 53
Number 6 54
Number 7 55
Number 8 56
Number 9 57
Left Soft Key 164
Right Soft key 165
Green Key 196
Red Key 197
Pencil 18
Backspace(C)-Key 1
Menu Key 180
Multimedia Menu Key 186
"Joystick Left" 14
"Joystick Right" 15
"Joystick Up" 16
"Joystick Down" 17
[OK]-Key 167
Gallery Key 230
Volume Up 162 (E55 lateral 1a de 3)
Volume Down 163 (E55 lateral 3a de 3)
Camera key (focus) 226
Camera key (take pic) 227
Power Off Key 166
Open Slider 168
Close Slider 169
???171 (E55 la de coger foto)
Open Multimedia Keys 172
Close Multimedia Keys 173
Multimedia Key Pause/Play 182
Multimedia Key Stop 183
Multimedia Key Forwards 184
Multimedia Key Backwards 185
Navigation key 239
???242 (E55 lateral 2a de 3)

Y tutorial (código) del wiki de Nokia sobre cómo capturar las teclas. A la llamada de CaptureKeyUpAndDowns() hay que añadirle al final el parámetro de prioridad, que en S60 3a ed. es "2" (hacer CaptureKeyUpAndDowns(codigo,0,0,2)).

Thursday, 25 March 2010, 4:44:26 pm
A vueltas con la seleccion de punto de acceso Aquí hay otro ejemplo de cómo evitarlo:
I think the best thing to do is to 1st
launch a dialog. Then when you see the connect to be ok, you save the iap_id to a file.

On subsequent starts you can use the id on the file to

...
RConnection iConnect;
RSocketServ iSocketServ; 
TCommDbConnPref iPref;
... 
rcode=iConnect.Stop();
iPref.SetDirection(ECommDbConnectionDirectionOutgoing);
iPref.SetDialogPreference(ECommDbDialogPrefDoNotPrompt);
iPref.SetIapId(aIapId);
iPref.SetBearerSet(KCommDbBearerUnknown/*PSD*/);
iConnect.Start(iPref);


Yes. This is higly nontrivial thing to do.



Otro método (suponiendo que la conexion se llama IBOX)
/*----------LANCIA IL LINKING ALLA RETE MEDIANTE IAP IBOX-------------------------*/
TBool CSocketsEngine::NetLinkL(TCallInitiator aCaller)
{
  TCommDbConnPref   Pref;
  CCommsDatabase    *CommDb;
  CCommsDbTableView *IapView;
  TInt     result;
  TUint    conncount;
  TUint32  IboxId=0;
  TBuf<80> STmp;
  TBool    Emulator= FALSE;
  TInetAddr LocAddr;

  /*----Initiate attempt to connect to a socket by IP address-------*/
  if( iEngineStatus==EGpDeadStop ) {
      iCallInitiator= aCaller;
      /*-----------------Apro IAP---------------------------------------------*/
      CommDb= CCommsDatabase::NewL(EDatabaseTypeIAP); // vuoto
      CleanupStack::PushL(CommDb) ;                   // da distruggere
      IapView= CommDb->OpenTableLC( TPtrC(IAP) );
      result= IapView->GotoFirstRecord();
      iIapName.Zero() ;
      while( result==KErrNone ) {
        IapView->ReadTextL( TPtrC(COMMDB_NAME), STmp) ;
        /*------emulatore->"NTRas GPRS" o "LAN_IAP_1"-------*/
        //Debug(STmp);
        if( STmp.Match(_L("IBOX")) != KErrNotFound ) {
            /*------trovato in lista----------------*/
            IapView->ReadUintL( TPtrC(COMMDB_ID), IboxId) ;
            iIapName.Copy(_L("IAP->(IBOX)")) ;
            break;
        }
        if( STmp.Match(_L("LAN_IAP_1")) != KErrNotFound ) {
            /*------trovato in lista----------------*/
            IapView->ReadUintL( TPtrC(COMMDB_ID), IboxId) ;
            iIapName.Copy(_L("IAP->(EMUL)")) ;
            Emulator= TRUE;
            break;
        }
        result= IapView->GotoNextRecord();
      }
      CleanupStack::PopAndDestroy(IapView);
      CleanupStack::PopAndDestroy(CommDb);
      /*---mostro IAP------------------*/
      Debug(iIapName);
      /*---------Per caso sono dentro all'emulatore?--------------------------*/
      if( Emulator ) {
          /*-----prendo indirizzo locale-------*/
          iLocalName.Copy(KDefaultEmulaName);
          //Debug(iLocalName);
          /*-----salto NetLinking--------------*/
          /*-----due passaggi in uno-----------*/
          ChangeStatus(EGpLinkedNoConn);
          if( iCallInitiator==IGpConnectCall ) {
              /*---comincio da capo----*/
              return ConnectL() ;
            }
            else { // IListenCall
              return ListenL() ;
          }
      }
      /*---------Apro la connessione IAP per attivare il link GPRS------------*/
      iConnection.Open(iSocketServ);
      iConnection.EnumerateConnections(conncount);
      if( conncount !=0 ) {
          DebugToFile(_L("Eng-Just Linked !"));
          ChangeStatus(EGpLinkedNoConn);
          if( iCallInitiator==IGpConnectCall ) {
              /*---comincio da capo----*/
              return ConnectL() ;
            }
            else { // IListenCall
              return ListenL() ;
          }
      }
      /*-----------------Sono proprio fuori-----------------------------------*/
      Pref.SetIapId(IboxId);
      Pref.SetDialogPreference(ECommDbDialogPrefDoNotPrompt);
      Pref.SetDirection(ECommDbConnectionDirectionOutgoing);
      iConnection.Start(Pref, iStatus);
      /*-----------------Cambio stato per RunL--------------------------------*/
      //Debug(_L("Deb-NetLinking !"));
      ChangeStatus(EGpNetLinking);
      /*-----------------Attivo evento timeout--------------------------------*/
      iTimer->After(KShortTO);
      /*-----------------Attivo evento completamento--------------------------*/
      SetActive();       // la Connection diventa pendente, attendi RunL
      return TRUE;
  }
  /*--fatto nulla--*/
  return FALSE;
}




Thursday, 4 March 2010, 7:41:17 pm
Instalando qt en el teléfono Hay que instalar (en este orden, están en dario@symbiandevel:~/symbian-sdks-qt-sis):
  • pips_s60_1_6_ss.sis
  • openc_ssl_s60_1_6_ss.sis
  • stdcpp_s60_1_6_ss.sis
  • qt_selfsigned.sis

Si se quiere usar un programa de prueba:
  • collidingmice.sisx

El collidingmice.sisx es firmado por nosotros, lo he firmado con:
$ ~/workspace/signsis.sh collidingmice.sis collidingmice.sisx ~/2010sicosoft-with-pubid11.cer ~/2010CertifSymbianSicosoft.pfx.key
Update: No le gusta el qt.sisx firmado por nosotros. Hay que usar el selfsigned (ya lo he corregido arriba).
Update2 Las instruccionesd eLizardo no funcionan correctamente en cuanto a generar los.sis. Las instrucciones corregidas en "The Zeroth"

Thursday, 4 March 2010, 6:21:18 pm
Instalado gnupoc-qt para S60 3.1 en chibiko Siguiendo las instrucciones, aunque antes de ejecutar el instalador he tenido que hacer:
 mkdir ~/tmp
 export TMPDIR=~/tmp
(ya que el /tmp no tenía espacio libre suficiente).

En symbiandevel no he podido instalarlo porque el fichero "/usr/include/sys/queue.h" es demasiado antiguo y falla al compilar algunas de las utilidades del gnupoc.

Friday, 12 February 2010, 4:32:03 pm (updated 4/03/2010)
Qt en Symbian S60 Getting started with Qt for Symbian. Installing Qt for Symbian SDK 4.6.2 on Linux

Tutoriales de Qt4 Tutorial básico Otro tutorial un poco más avanzado

Thursday, 11 February 2010, 5:22:23 pm
eselect en PIPS Versiones recientes de PIPS disponen de una función llamada eselect que permite esperar simultaneamente a "fd_sets and a number of arbitrary TRequestStatus variables". Sitio de descarga de openc/PIPS.

Wednesday, 20 January 2010, 6:47:26 pm
Modifico tctiserver para que acepte localizaciones forzadas en los ficheros auth Es un parámetro adicional, después de la descripción.

Monday, 18 January 2010, 4:58:54 pm
BSSID (AP MAC) en Symbian Se puede obtener usando el WLAN Info API. Sólo he encontrado más informacion sobre MACs que era para ver la información de mi propia MAC (TSS000462), el resto usan el WLAN_Info_API plug-in (TSS000682). Ejemplo de usar el apli privado: Aquí (cache), o todo el thread (slightly mangled).

Más información de obtener el BSSID y ejemplos con la siguiente búsqueda Google:"InformationElement( KWlan802Dot11SsidIE".

Notas sobre el uso de las configuraciones en Symbian Este Commit de Qt, buscar "s60" y ahí están las funciones de acceder a las configuraciones, que sirven como ejemplo (están bien identadas, hacen el uso correcto de las clases de symbian, etc). Eso sí, es código "pre-release".

¿Alternativa? Connection Monitor Server API Resulta que puedes obtener casi todo, pero el BSSID no aparece por ningún lado :-/.

Friday, 4 December 2009, 7:10:46 pm
Código para buscar un IAP por nombre En este post y este docuemento ("leyendo los access points"):
TInt CConectionRequest::GetAcessId() 
{
   TUint32 iapID;
   // open the IAP communications database 
   CCommsDatabase* commDB = CCommsDatabase::NewL(EDatabaseTypeIAP);
   CleanupStack::PushL(commDB);
   CCommsDbTableView* commDbTableView = commDB->OpenTableLC(TPtrC(IAP));
   CCommsDbConnectionPrefTableView* commDBView = 
          commDB->OpenConnectionPrefTableInRankOrderLC(
          ECommDbConnectionDirectionOutgoing);
   TInt err;
   TBuf<128> iapName;
   // Point to the first entry
   if (commDBView->GotoFirstRecord() == KErrNone) {
      do {
         commDbTableView->ReadTextL(TPtrC(COMMDB_NAME), iapName);
         if(iapName.Compare(_L("yourdesiredapn(Airtellive(say))")) == 0) {
            commDbTableView->ReadUintL(TPtrC(COMMDB_ID), iapID); 
            break; 
         }
         err = commDbTableView->GotoNextRecord();
      } while (err == KErrNone);
   }
   CleanupStack::PopAndDestroy(commDBView);
   CleanupStack::PopAndDestroy(commDbTableView);
   CleanupStack::PopAndDestroy(commDB);
   return err;
}


Además (según esa misma thread), para filtrar directamente por tipo de Bearer (ejemplo para GPRS, nosotros lo queremos para Wifi), sería:

One more suggesion:
instead of using
Code:

CCommsDbConnectionPrefTableView* commDBView =
  commDB->OpenConnectionPrefTableInRankOrderLC(
  ECommDbConnectionDirectionOutgoing);

and then sorting outgoing connections with
Code:

if ( serviceType.CompareF( TPtrC( OUTGOING_GPRS) ) == 0 )

you can directly use
Code:

CCommsDbTableView* commsDbGprsTableView=
  commsDB->OpenIAPTableViewMatchingBearerSetLC(
  ECommDbBearerGPRS,ECommDbConnectionDirectionOutgoing);

which will directly give only those APIs whose
bearer type is GPRS and direction outgoing.

Regards,
Suyash.



Update Según parece, si filtras usando lo de iCommsDB->OpenIAPTableViewMatchingBearerSetLC() para los ECommDbBearerWLanEApBearerTypeWLAN obtienes un bonito panic. Hay que filtrar usando CApSelect para filtrar para un TApBearer (EApBearerTypeWLAN en nuestro caso). Ejemplo de uso de CApSelect:
CCommsDatabase* commDb =
    CCommsDatabase::NewL(EDatabaseTypeIAP);
CleanupStack::PushL(commDb);
CApSelect* select = CApSelect::NewLC(
    *commDb,
    KEApIspTypeAll,
    EApBearerTypeWLAN, // use EApBearerTypeAll for all types
    KEApSortUidAscending);
TBuf<256> accessPoints;
_LIT(KAPInfoTxtFormat, "[%d]%S ");
TBool ok = select->MoveToFirst();
for(TInt i = 0; ok && (i < select->Count()); i++)
    {
    accessPoints.AppendFormat(
        KAPInfoTxtFormat,
        select->Uid(),
        &select->Name());
    ok = select->MoveNext();       
    }
CleanupStack::PopAndDestroy(2); // select, commDb
// accessPoints descriptor now contains WLAN AP IDs + names 


Tuesday, 24 November 2009, 6:58:36 pm
Para hacer que funcione el modo ap con el ath5k (kernel etchnhalf) Se usa esta guía.

Update 20091127 Restaurado el funcionamiento del wifi para el teléfono symbian usando el núcleo antiguo y el driver de madwifi (uff!!). Tenía todavía el antiguo br0 para cisco levantado (desde el /etc/init.d/networking, y eso hacía que el teléfono no cogiese IP por DHCP; lo he quitado) y se han hecho otros cambios (poner un canal menos concurrido, hacer que se levante el interfaz en el modo master usando el método recomendado en el howto de gentoo, definir un interfaz dummy0 con la nueva IP de main1...).

Monday, 23 November 2009, 6:23:57 pm
Hidden ssid con madwifi Resulta que la manera de poner el "hidden ssid" es:
 ifname=ath0 ; hidden=1 ; iwpriv "$ifname" enh_sec "$hidden"

Pero madwifi no soporta ese comando :-(

Friday, 20 November 2009, 5:31:27 pm
Ya se pone la aplicación en segundo plano con el softkey de salir Siguiendo el código de aquí modificado con este otro para usar UIDs en vez de literales. También se puede capturar la tecla roja (pero si ya estás tratando el EAknSoftkey no hace falta, ya que envía ese comando).

Cuando se pulsa flecha izqda en las instancias se va los subsistemas Ya que si no, navegar entre diferentes subsistemas es muy pesado.

Marco la versión actual de la aplicación como 1.0 ¡Por fin! Aunque todavía no acepta conexiones entrantes (habrá que investigar por qué...).

Thursday, 19 November 2009, 7:09:15 pm
Información adicional sobre obexftp En esta página. Básicamente es que se pueden mandar ficheros en vez de "Mensajes". Se hace de la siguiente manera:
 obexftp -b00:12:D1:04:66:21 --chdir C:\\Data\\Documents --list
 obexftp -b00:12:D1:04:66:21 --chdir C:\\Data\\Documents --put TCM/sis/TCM_S60.sisx
 obexftp -b00:12:D1:04:66:21 --chdir C:\\Data\\Documents --delete TCM_S60.sisx

Para mandar .sis y ficheros ocultos a través de Bt en un Symbian Según esta página basta usar YBrowser con los plugins. Alternativamente se puede hacer una aplicancioncilla que también lo haga. He probado el YBrowser (después de firmarlo) y funciona perfectamente para mandar los .sisx a otros teléfonos symbian :).

Thursday, 19 November 2009, 6:41:30 pm
Conseguido: ya coge la MAC del socket servidor Obtiene la MAC del socket servidor. Es un pelín más lento en coger el listado inicial pero merece la pena.

Thursday, 19 November 2009, 5:43:31 pm
Update: documentación Symbian_OS_Communications_Programming/3._An_Introduction_to_ESOCK

A vueltas con los sockets servidores De este post. Copio el código porque luego "desaparecen" los posts...

NOTA: También en razonable leer este post de NewLC.

// Server Socket Definition
class MySocket public CActive
{
   public:
      MySocket();
      ~MySocket();
   public:
      void AcceptL();
      TInt Send();
      TInt Recv();
      void RunL() ;
      void StartL();
      void StopL();
      void DoCancel();
      void Initialize();
   public:
      RTimer iTimer;
   protected:
   private:
      RSocket *iSocket;
      RSocketServ iServer;
      TInetAddr addr;
      RSocket blanketSocket;
      TRequestStatus status;
      TInt result;
};

// Server Socket impl
void 
MySocket::Initialize()
{
   TInt result;
   iServer.Connect();

   result = iSocket->Open(iServer,KAfInet, KSockStream, KProtocolInetTcp);
   User::LeaveIfError(result);

   result = blanketSocket.Open(iServer);
   User::LeaveIfError(result);

   addr.SetPort(3100);
   addr.SetAddress(INET_ADDR(157,78,70,100));
   addr.SetFamily( KAfInet );

   result = iSocket->SetOpt(KSONonBlockingIO,KSOLSocket);
   result = iSocket->Bind(addr);
   result = iSocket->Listen(1);
}

void
MySocket::RunL()
{
   iTimer.After(iStatus,0);
   AcceptL();
   SetActive();
}

void
MySocket::AcceptL()
{
   TUint localPort;
   TInetAddr localAddress;
   TBuf8<256>data;
   TInt available = 0;
   iSocket->Accept(blanketSocket,status);
   User::WaitForRequest(status);

   blanketSocket.LocalName(localAddress); 
   localPort = blanketSocket.LocalPort(); 

   blanketSocket.Read(data,status); 
}


Wednesday, 11 November 2009, 7:20:38 pm
Para notificaciones de alarmas Basta con hacer dos cosas:
  1. Que cuando se da "salir" en la aplicación de TCM lo que haga sea realmente ponerla en segundo plano (Symbian cuando intentas volverla a arrancar lo que hace es ponerla otra vez en primer plano). Si realmente se quiere salir de la aplicación basta con ir a la lista de tareas (tecla menú durante 5 segs), ponerse encima de TCM y dar a la tecla "C" (y después dar al botón del joystick para volver a la pantalla principal, que si no te quedas esperando en la pantalla de la lista de tareas).
  2. Hacer que espere conexiones TCP en un puerto. Al recebir una alarma por ese puerto, la ha de añadir a la tabla de alarmas como la primera y ponerse delante con la tabla de alarmas (ffartaría ver cómo notificar al usuario y que si la apli está en primer plano sólo notificar, no poner automáticamente la tabla de alarmas). Además ese puerto se puede usar además para obtener la MAC propia (conexión a sí mismo usando la IP del extremo local de la conexión contra tctiserver pero con los API de symbian en vez de con los de PIPS, y después preguntarse por la MAC).

Thursday, 22 October 2009, 6:45:33 pm
Symbian foundation libera el kernel EKA2 de Symbian OS con licencia Eclipse Ver el blog de symbian. Incluye los fuentes del kernel EKA2, un qemu modificado para ello, un compilador ARM y un port a la Beagleboard. El kernel EKA2 y programas relacionados se pueden bajar aquí.

Friday, 18 September 2009, 6:59:19 pm
Retomando el background app Hace falta hacer un demonio en Symbian 9.x para que acepte conexiones con alarmas, y que las meta en mensajes en el inbox. También hay que hacer que TCM sea el visor de dichos mensajes (han de tener un MIME determinado y hacer un recognizer (wiki) de ese MIME, y loego establecer un handler para ese tipol). Por último, hay que hacer un autostart del demonio que habíamos indicado antes.

Wednesday, 9 September 2009, 6:32:27 pm
Para recibir ficheros via bluetooth (movil a PC) En symbiandevel se hace lo siguiente:

1. Se lanza el bluetooth-properties y se pone el tiempo de visibilidad a "never invisible"
2. Se hace en el directorio en el que quieres recibir los ficheros un:
 $ obexpushd -n
3. En el teléfono los vas enviando por bluetooth a symbiandevel-0
4. Cuando hayas terminado, das control+c para para al obexpushd
5. Vuelves a poner en el bluetooth-properties y se pone el tiempo de visibilidad a 3min.

Wednesday, 9 September 2009, 4:54:42 pm
Capturar pantallas en Symbian (para hacer el manual) Se usa al Screenshot for Symbian OS (es Open Source). Lo he dejado instalado el en E60, y se captura una imagen (png) con EDIT+*.

Tuesday, 8 September 2009, 4:57:56 pm
Simulador de tctiserver/plano en SICO En symbiandevel, se abren dos ventanas con lo siguiente:

symbiandevel$ cd /home/dario/tctiserver
symbiandevel$ ./sim_tctiserver.sh

Y en la segunda ventana:

symbiandevel$ cd /home/dario/tctiserver
symbiandevel$ ./sim_plano.sh

Para pararlos, se hace Ctrl-Z y luego un "kill %1" en cada ventana.

Si hace falta simular más cosas, se pueden capturar las acciones yéndose a rdsi2 y desde ahí te conectas a "main1:10003", luego te identificas con lo mismo que se identifica el teléfono contra el simulador, y luego te conectas al plano correspondiente con un telnet "ip_plano:10001", y le vas mandando los comandos que te dice el simulador que acción no soportada. Se copia la respuesta a un fichero con el nombre canned_nombreaccionsegunsimulador.txt y ya está.

Tuesday, 1 September 2009, 7:34:58 pm
Generado el nuevo certificado para symbiansigned, así como probado que podemos pedir nuevos IMEIs Se ha hecho usando el firefox de symbiandevel, y el certificado:
lsdario@symbiandevel:~$ ls 2010*
2010CertifSymbianSicosoft.pfx      2010CertifSymbianSicosoft.pfx.key.ossl
2010CertifSymbianSicosoft.pfx.cer  2010sicosoft-with-pubid0.cnf
2010CertifSymbianSicosoft.pfx.key  2010sicosoft-with-pubid0.csr


El resultado está en
 symbiandevel:/home/dario/Desktop/2010sicosoft-with-pubid0.cer

URL: https://www.symbiansigned.com/app/barclayhtml/devcert/uploadPublisherId.jsp

Wednesday, 26 August 2009, 6:22:55 pm
Más sobre sockets en symbian Si la aplicación de red se te queda esperando eternamente... ejemplo de RSocketRead. Conversión del ejemplo anterior a RecvOneOrMore.

Wednesday, 26 August 2009, 6:19:17 pm
Probando con el teléfono en "local" Para el servidor:
dario@symbiandevel:~/tctiserver$ while true ; do cat canned_server.txt | nc -l -p 10003 ; done

El contenido de canned_server.txt:
check SIP:1602EM2@37.129.52.100 1/3 17.138.58.67 Pacifico 0
check SIP:1602EM2@37.129.52.100 2/3 17.65.58.243 Canillejas 1
check SIP:1602EM2@37.129.52.100 3/3 16.4.254.178 "Aula Estaciones Canillejas" 0


Si se quiere probar al completo, se hace de la siguiente manera:

En symbiandevel:

dario@symbiandevel:~/tctiserver$ ./tctiforward 172.16.2.2 172.16.1.2

Y en rdsi2:

metro@FrontPCI02:/incoming$ ./tctiforward 150.100.122.31 17.138.58.67

PERO por ahora la aplicación tiene un proble y con las latencias de tantas redirecciones falla muchas veces (cosas del symbian; si no hay latencias todo funciona muy bien).


Monday, 24 August 2009, 7:28:59 pm
Symbian frustrations Este post....

Thursday, 30 July 2009, 5:06:54 pm
He generado documentación con doxygen de los ficheros de cabecera de epoc32 Generado con las instrucciones de doxygen cheat sheet, haciendo lo siguiente:
dario@symbiandevel:~/epoc32$ doxygen Doxyfile
Y los resultados los ha dejado en
symbiandevel:/home/dario/epoc32/doc

Thursday, 30 July 2009, 4:28:23 pm
FIONREAD ioctl en Symbian Según este post se hace así:

iSocket.SetOpt(KSONonBlockingIO, KSOLSocket);
iSocket.GetOpt(KSONonBlockingIO, KSOLSocket, boolean);
if (boolean) {
    RSocket::Read(aBuf, aStatus), 
}  
//Pool again if aStatus == KErrWouldBlock  


Mas código:
TPckgBuf<TInt> pckLen(0);
TInt len = 0;
// determine when data are available for reading
iSocket.GetOpt(KSOReadBytesPending, KSOLSocket, pckLen);
len = pckLen();


Cambiar un socket de bloqueante a no-bloqueante Del mismo post:
RSocket->GetOpt(KSOSelectPoll, KSOLSocket, aValue);
if(aValue & KSockSelectRead)
	; //Something to read


Hacer un select en un socket Según este post se hace de la siguiente manera:

void
SymbianCore::GetFavouriteIap()
{
   CCommsDatabase* cdb = CCommsDatabase::NewL(EDatabaseTypeIAP);
   CleanupStack::PushL(cdb);

   CCommsDbConnectionPrefTableView* commDBView = 
      cdb->OpenConnectionPrefTableInRankOrderLC(ECommDbConnectionDirectionOutgoing);
   if(commDBView->GotoFirstRecord() == KErrNone) {
      CCommsDbConnectionPrefTableView::TCommDbIapConnectionPref pref;
      commDBView->ReadConnectionPreferenceL(pref);
      m_uIapID = pref.iBearer.iIapId;
   }

   CleanupStack::PopAndDestroy(commDBView);
   CleanupStack::PopAndDestroy(cdb);
}



Friday, 24 July 2009, 7:04 pm
Sobre lo de usar RSubSession para no preguntar sobre el socket Según este post: "RSocket::Connect is a wrapped RSubSessionBase::SendReceive - it does not check if you pass valid/invalid, existing/non-existing argument, thus it can not block your code"- Eso significa que debe haber una forma de sacar el RConnection desde el RSocket.

Obtención del "Preferential IAP" (es el de por defecto) En este post:
TInt err = iSocketServ.Connect();//iSocketServ is "RSocketServ"

if ( ( KErrAlreadyExists != err ) && ( KErrNone != err ) ) 
   User::Leave( err );

err = iConn.Open( iSocketServ );//iConn is "RConnection"

if ( ( KErrAlreadyExists != err ) && ( KErrNone != err ) ) 
   User::Leave( err );

TCommDbConnPref connPref;
connPref.SetIapId( aIAPId );
connPref.SetDialogPreference( ECommDbDialogPrefDoNotPrompt );
connPref.SetDirection( ECommDbConnectionDirectionOutgoing );
        
iConn.Start(connPref);  

err = iSocket.Open( 
   iSocketServ, KAfInet, KSockStream, KProtocolInetTcp, iConn );

if ( ( KErrAlreadyExists != err ) && ( KErrNone != err ) ) 
  User::Leave(err);

RHostResolver hostResolver;
TNameEntry entry;

User::LeaveIfError(hostResolver.Open(
   iSocketServ, KAfInet, KProtocolInetUdp, iConn ) );
CleanupClosePushL( hostResolver );
         
User::LeaveIfError( hostResolver.GetByName( aDomain, entry ) );
            
if ( !TInetAddr::Cast( entry().iAddr ).IsWildAddr() ) {
   TInetAddr addr = TInetAddr::Cast( entry().iAddr );
   addr.SetPort( aPort );
                
   CleanupStack::PopAndDestroy();//hostResolver
    
   iSocket.Connect( addr, iStatus ); 
        
   SetActive();
}


Ejemplo (con posible bug de tener el socket/RConnection no establecidos al mismo RSockServ) de selección por apliación de IAPID En Este post.

Ejemplo de conexión sin que aparezca el UI de selección de IAP De este post:

// RTimer CBlah::RecvTimer;

void
CBlah::AFunctionThatCanTimeOut()
{
   iSocket.RecvOneOrMore(str, 0, iStatus, aLen); 
   RecvTimer->Start(10000000,1*10000000000,TCallBack(RecvTimerCallBack,this)); 
   SetActive();
}

// Then in your timer callback:

TInt
RecvTimerCallBack(TAny* aArgs)
{
   CBlah* p = (CBLah*)aArgs;
   p->iRecvTimer->Cancel();
   TRequestStatus* p = &pProcessor->iStatus;
   User::RequestComplete(p, KErrTimedOut);
}

// Then in your RunL()

CBlah::RunL()
{
   iRecvTimer->Cancel();
   if(iStatus.Int() == KErrTimedOut) {
      // it timed out.
   }
}

I write all the code above in a method of initialization, and share a socket to read and write "RSocket":iSocket.
Server domain(aDomain) , port(aPort ) andIAPId(aIAPId) are correct.


Update 20090728: El código de los dos puntos anteriores es correcto y funciona perfectamente (¡yay!). Sólo mencionar que faltaba la referencia a incluir en el MMP el commdb.lib y que el código ese necesita incluir los ficheros de cabecera commdb.h y commdbconnpref.h .

Thursday, 23 July 2009, 6:36 pm
Timeout de envío/recepción en sockets Este post.

_LIT(KFmtCStr,"C-String: %s\n");
_LIT(KFmtDesc,"Descriptor: %S\n");
TBuf<128> buf(KStringOne);
TUint cstrBuffer[100];
// Zero-fill the buffer
memset(cstrBuffer,0,sizeof(cstrBuffer));
// Copy descriptor data to the C-string
memcpy(cstrBuffer,buf.Ptr(),buf.Size());
console->Printf(KFmtCStr,cstrBuffer);
// Make the opposite conversion
// PtrZ() method will add NULL character to the end of descriptor's data
const TText* text = buf.PtrZ();
console->Printf(KFmtCStr,text);


Monday, 20 July 2009, 6:48:57 pm
Pasando descriptores de C a Symbian y viceversa Del Descriptors+Cookbook.pdf:

class MyAO : public CActive
{
RXX iAOObj;
}

void MyAO::AsynchronousFun()
{
        iAOObj.IssueAsynOpr( iStatus );
        SetActive();
}

void MyAO::RunL()
{
        // called after IssueAsynOpr finishes
}


What can go wrong: If the descriptor's size is not large enough to accommodate an additional
NULL character in the TDes::PtrZ() call, then you'll get a panic USER 23.


Friday, 17 July 2009, 7:08:41 pm
A vueltas con el IAP ID (para seleccionar el AP WiFi automáticamente) Según el Wiki de Nokia, la manera de hacerlo es...
 connection.GetIntSetting(KIapIdSettingName, iapId)

Friday, 10 July 2009, 5:28:54 pm
Ejemplo de CActive De aquí:

TPtr TDesCDerivedClass::RightL(TInt aLength) const
{
        if (aLength < 0) 
                User::Leave(KErrArgument);
        TInt len=Length();
        if (aLength>len)        
                aLength=len;
        return(TPtr((TUint16*)Ptr()+len-aLength,aLength,aLength));
}



Thursday, 9 July 2009, 5:11:05 pm
Noticia: Nokia posiciona Qt como el interfaz dominante para desarrollar para Symbian Symbian S60: Orbit and DirectUI vs Avkon. Avkon tiene los días contados, así como las idiosincrasias de desarrollar para symbian... habrá que despedirse de los descriptores y los objetos activos (a los que se ha dedicado en esta página gran esfuerzo para comprenderlos...). Supongo que la noticia se refiere a este post en blog.symbian.org.

A tener en cuenta:
  • fechas:

Symbian releasebetarelease/hardened/debugged
Symbian^2fin de 2009Q2hardened fin de 2009Q4
Symbian^32009Q4 hardened 2010Q2
Symbian^42010Q2 hardened 2010Q4

  • A partir de Symbian^4 las aplicaciones se harán en Qt. Los .sis de Qt se backportearán para Symbian^2 y ^3.
  • Sólo se quita la parte de Avkon; los descriptores y objetos activos permanecen si quieres usarlos.
  • Qt no es "as-is", sino que se usará el Qt API, widgets especiales para la plataforma ("Orbit"), y todo eso con un layout determinado (finger-optimised "Direct UI").

Wednesday, 8 July 2009, 7:09:47 pm
Romper la seguridad de Symbian S60 3rd Link. Howto: hack_perms_s60v3.txt ficheros necesarios.

Wednesday, 8 July 2009, 6:23:08 pm
Generación de punteros TPtr a la mitad de un descriptor En el Descriptors+Cookbook.pdf (está en /home/dario/Programacion/doc/s60/Descriptors+Cookbook.pdf), dan el siguiente código de ejemplo:
// Create RBuf
RBuf rBuf;
rBuf.CreateL(6);
// Put to the cleanup stack
rBuf.CleanupClosePushL();
// Do something: copy, resize and append
_LIT(KHello, "Hello ");
_LIT(KWorld, "World!");
rBuf.Copy(KHello());
rBuf.ReAllocL(12);
rBuf.Append(KWorld);
// Close and destroy
CleanupStack::PopAndDestroy();
// or point to some other buffer:
// RBuf::Assign
HBufC* hBuf = KHello().AllocL();
rBuf.Assign(hBuf);
// Do something and then cleanup
...


De lo cual se deduce que llamando a descriptorvar.Ptr() se obtiene un puntero convencional a los datos del descriptor, y con el constructor TPtr(puntero_a_datos,longitud_datos) se construye un descriptor-puntero nuevo.

Otro ejemplo de uso de RBuf También del Descriptors+Cookbook.pdf:
_LIT(KTxtMatchstr1,"*World*");
_LIT(KTxtMatchstr2,"*W?rld*");
_LIT(KTxtMatchstr3,"Wor*");
_LIT(KTxtMatchstr4,"Hello");
_LIT(KTxtMatchstr5,"*W*");
_LIT(KTxtMatchstr6,"hello*");
_LIT(KTxtMatchstr7,"*");

TBufC<8> matchstr[7] = {
                       *&KTxtMatchstr1, // "*World*"
                       *&KTxtMatchstr2, // "*W?rld*"
                       *&KTxtMatchstr3, // "Wor*"
                       *&KTxtMatchstr4, // "Hello"
                       *&KTxtMatchstr5, // "*W*"
                       *&KTxtMatchstr6, // "hello*"
                       *&KTxtMatchstr7  // "*"
                       };

myfunction(matchstr[0]);


Por último, ejemplo de un array de TBuf

myRBuf.CleanupClosePushL();
...
const TInt newLength = myRBuf.Length() + appendBuf.Length();
if (myRBuf.MaxLength() < newLength)
      {
      myRBuf.ReAlloc(newLength);
      }
myRBuf.Append(appendBuf);
...
CleanupStack::PopAndDestroy();   // calls myRBuf.Close();


Performance Tuning Symbian C++: 13 issues of Performance tuning of code Da 13 problemas comunes de rendimiento en Symbian C++; muchos de ellos están relacionados con descriptores.

Monday, 6 July 2009, 7:35:46 pm
Uso de RBuf Hay un Documento que explica el uso de RBufs: /home/dario/Programacion/doc/s60/Introduction_to_RBuf_v1.0.pdf . El ejemplo más básico de su uso para almacenar datos dinámicos es el siguiente (requiere usar ReAlloc()s explícitos, no lo hace de forma automática):
_LIT(KTextHello, "Hello");
_LIT(KTextWorld, " World");
RBuf myRBuf;
myRBuf.CleanupClosePushL();
myRBuf.CreateL(KHello());
imyRBuf.ReAllocL(KHello().Length() + KWorld().Length());
myRBuf.Append(KWorld);
CleanupStack::PopAndDestroy() // calls myRBuf.Close();


Otro ejemplo:
RBuf myRBuf;
TInt maxSizeOfData = 20;
if (myRBuf.Create(maxSizeOfData)) != KErrNone)
      {
      ...   // error handling
            // (omitted from subsequent code examples for clarity)
      }


Y otro:

RBuf mySocketName;
...
if(mySocketName.IsNull())
    {
    mySocketName.CreateL(KMaxName);
    }
aMessage.ReadL(aMessage.Ptr0(), mySocketName);


Y un úotimo ejemplo:
#include <etel3rdparty.h>
//----------------------------
class C_imei: public CActive{
   CTelephony *telephony;
   CTelephony::TPhoneIdV1 iV1;
   CTelephony::TPhoneIdV1Pckg iPkg;
   TBuf<50> imei;

   CActiveSchedulerWait asw;
public:
   C_imei::C_imei():
      CActive(EPriorityStandard),
      telephony(NULL),
      iPkg(iV1)
   {}

   void ConstructL(){
      telephony = CTelephony::NewL();
   }

   ~C_imei(){
      Cancel();
      delete telephony;
   }

   void GetIMEI(Cstr &str){
      CActiveScheduler::Add(this);
      telephony->GetPhoneId(iStatus, iPkg);
      SetActive();
      asw.Start();
      Deque();
      const wchar_t *wp = (wchar_t*)imei.PtrZ();
      str.Copy(wp);
   }

   void DoCancel(){
      telephony->CancelAsync(CTelephony::EGetPhoneIdCancel);
   }
   void RunL(){
      if(iStatus == KErrNone)
         imei = iPkg().iSerialNumber;
      asw.AsyncStop();
   }
};
//----------------------------
void ReadDeviceSerialNumber(Cstr &imei){

   C_imei *im = new(ELeave) C_imei;
   CleanupStack::PushL(im);
   im->ConstructL();
   CleanupStack::Pop(im);
   im->GetIMEI(imei);
   delete im;
}


Monday, 6 July 2009, 7:22:15 pm
Tabla comparando funciones de cadenas de C con las de descriptores Aquí está:

C functionSymbian ReplacementMeaning
sprintf, swprintfTDes::FormatWrite formatted data to a string.
strcat, wcscat,
strncat, wcsncat
TDes::AppendAppend string to another.
strcmp,
strncmp, wcsncmp
TDesC::CompareCompare strings lexicographically.
strcpy, wcscpy
strncpy, wcsncpy
TDes::CopyCopy string to another.
strchr, wcschrTDesC::LocateFind a character in a string.
strrchr, wcsrchrTDesC::LocateReverseScan a string for the last occurrence of a character.
strspn, wcsspn-Scan index of the first character
from string that doesn't exist in
alphabet array.
strcspn, wcscspn-Scan the index of the first
occurrence of a character in string
that belongs to the set of
characters.
strstr, wcsstrTDesC::FindFind a substring.
strtok, wcstokTLex::Find the next token in a string.
strlen, wcslenTDesC::LengthGet the length of a string.
strcoll, wcscollTDesC::CompareCCompare strings using locale-specific information.
strftime,wcsftimeUsing TDes::Format
and TTime
Format a time string.
Fuente: Pág. 24 de este docuemento Symbian_OS_Descriptors_For_Text_And_Binary_Data_With_Example_v1_0.zip

Monday, 6 July 2009, 6:41:05 pm
Descriptors (referencia) Bueno, por fin tengo una idea bastante razonable de lo que son los descriptors, cómo elegirlos y cómo se usan. Los descriptors existentes son: TBufC, TBuf, TPtrC, TPtr, HBufC y RBuf.

Inicialmente sólo se consideran los TBuf/TBufC. Son los de uso "habitual". El TBufC sólo se puede usar para generar una cadena usando un _LIT como intermediario. Al TBuf se le puede modificar su contenido.

El TPtr/TPtrC se usan como punteros a TBuf/TBufC (o a tros descriptores) de manera que puedas devolverlos en un return (sólo se permiten returns de TPtr, TPtrC y HBufC).

El HBufC es cuando quieres que sean como punteros convencionales; obtienes memoria dinámica para ellos en creación y después puedes pasarlos en parámetros y como valroes de return siguiendo los manejos habituales de C, no de Symbian.

Por último está lo del RBuf que es un HBufC "alargable".

Y lo del TDes/TDesC es para que las funciones que reciben un descriptor como parámetro, no tengan que especificar si es un TBuf o un HBufC o un RBuf (eso para TDes; TDesC para sus versiones "constantes").

P.D.: Una cosa más: lo del 8 o 16 que sigue el descriptor (TBuf8) es para decir si lo quieres para uso de cadenas UNICODE (si no dices nada o si pones 16, p.ej. TBuf o TBuf16), o para datos binarios o que vas a enviar/recibir por un socket (TBuf8).

P.D.2: Para modificar un HBufC, se una un TPtr intermedio (¿por qué HBufC no es HBuf? Ni idea). Ver aquí.

Monday, 6 July 2009, 5:28:10 pm
Obteniendo el MAC address Código para obtenerlo mientras estás conectado.

Friday, 3 July 2009, 6:15:37 pm
Ejemplo de active objects (ejemplo para adaptarlo a Qt, pero vale) Active Object wrapping in Qt exaomple Aunque sea para Qt en S60, es uno de los mejores ejemplos de Active Objects que he visto hasta el momento.

Ejemplo de uso del Socket Server También gracias a los chicos de Qt, Tabla de uso de Sockets en S60.

Uso de sockets para UIQ la parte que no es de UI tb. vale para S60. Communications - UIQ books.

ELeave and TRAP, Cleanup Stack Artículo que explica los Leaves y la Cleanup Stack.

Descriptor FAQ: Passing descriptors Descriptors FAQ: How do I use descriptors as parameters?. Además, si te lees el de return types, la conclusión es que sólo se pueden devolver con un return los tipos HBufC* y TPtr/TPtrC (estos sin * ni &).



Tuesday, 30 June 2009, 7:20:17 pm
Usar fichero .c tanto en Linux como en Symbian El compilador de Symbian define __SYMBIAN32__, con lo que se puede separar el código con un simple
#ifdef __SYMBIAN32__
#endif

Tuesday, 30 June 2009, 6:57:14 pm
Obteniendo el IMEI Según este thread. Aquí hay código para conseguirlo usando Active Objects, ver segundo ejemplo (la manera de PlpVariant a la que se menciona en otros posts, que es muy sencilla, sólo funciona para 2nd Edition :-/ ):
        /* Ponemos un AP por defecto */
        {
                static char *APs[]={"Metro Madrid", "WiFiAP"};
                int i;
                struct ifreq ifr;
                for(i=0;i<(sizeof(APs)/sizeof(APs[0]));i++) {
                        strcpy(ifr.ifr_name, APs[i]);
                        if(ioctl(fd,SIOCSIFNAME,&ifr)==0) {
                                if(ioctl(fd, SIOCIFSTART, &ifr)==0)
                                        break;
                        }
                }
        }


Cuando dice "Cstr" al final hay que cambiarlo por el tipo de allocateador de cadena que quieres usar.

Requiere Capability ReadDeviceData

Tuesday, 30 June 2009, 5:59:21 pm
Active objects En este documento mencionan que hay un tutorial para el uso de Active Objects en CActiveAndFriends.pdf (está en ~/Progracion/doc/s60/).

Tuesday, 30 June 2009, 5:12:37 pm
Cambiar la aplicación de la tecla izq/der Se hace con "Menu -> Ajustes -> Teléfono -> Modo en Espera -> Tecla selección izq/der".

Friday, 26 June 2009, 6:50:41 pm
Firmar un .SIS online (actualizado) Con el cambio de symbiansigned.com a la fundación symbian (symbian.org), han cambiado la página para firmar un .SIS online: Open Signed Online. Genera ejecutables firmados para un solo IMEI.

Friday, 29 May 2009, 6:12:22 pm
Mandar SMSs con un móvil usando bluetooth Error: this should not happenHowto para interrrogar al movil y mandar un SMS>http://www.esdebian.org/wiki/de-interrogar-movil-enviar-sms. Básicamente es:
Buscar al móvil:
hcitool scan
Buscar el canal (channel)
sdptool browse xx:xx:xx:xx:xx:xx
Conectarse al canal
rfcomm connect 0 xx:xx:xx:xx:xx:xx 3&
Poner la clave de seguridad en el móvil
Poner la clave de seguridad en el PC
Comprobar la conexión
rfcomm
Ejecutar un programa de comunicaciones serie (cu o minicom)
cu -l rfcomm0 -s 9600
Después del connect comprobar que se ha conectado correctamente
at
Al recibir el "OK", mandar uno de los siguientes comandos:
ComandoDescripción
at+cgmiver la marca del movil
at+cgmmver la marca y el modelo
at+chupcuelga la llamada actual, en caso de estar esta activa
at+cpbf=?informar de la estructura de la agenda
Decuelve: CPBF: x,y donde "x" indica la máxima longitud del campo numérico y "y" la máxima longitud del campo de texto
at+cpbrmas información de la agenda
Devuelve: 3 valores, por ejemplo +CPBF (1-250),50,14 que significa que podemos meter hasta 250 elementos en la agenda con las características comentadas en el anterior comando
at+cpbr=5ver el elemento 5 de la agenda
at+cpbr=2,20ver ese intervalo de elementos en la agenda
at+cpbs?donde se almacenan los datos de la agenda
Devuelve:+CPBS "SM",101,250 lo cual indica que se esta usando la tarjeta SIM y se tienen ocupados 101 elementos de 250
at+cpbw=?formato de la agenda
at+cpbw=[index],[numero],[type],[texto]insertar un elemento en la agenda
Ejemplo:at+cpbw=102,"9xxxxxxxxx",129,"Pepe el del bar"
El tipo indica si el numero va precedido de + o no
at+cscaservidor de mensajes SMS
at+gswnúmero de serie del movil
atd;hacer una llamada
Ejemplo:atd91xxxxxxxx;
atd>num;llamar a un número almacenado en la agenda
atd>"Pepe el del bar";llamar a un numero por el nombre
at+cmgf=1activa el modo de texto para los SMS que veremos en el siguiente comando
at+cmgs="num"texto a enviarenvia un SMS a un número de movil
CR es un retorno de carro. Pulsar CTRL+Z para indicar que hemos acabado de escribir.





















Thursday, 7 May 2009, 4:12:25 pm
Terminal alternativo: Nokia E52 (mejor batería) Nokia Launches Extra Long-Lasting E52. Especificaciones (de). Básicamente es un teléfono Symbian S60 3rd FP2, con wifi, cámara y GPS, pero que tiene una autonomía de conversación de 8 horas.

Wednesday, 11 March 2009, 9:48:38 am
Wireless Tools for Linux Información general y utilidades para configurar diagnosticar una conexión Wifi en Linux: Wireless Tools for Linux

Tuesday, 16 September 2008, 2:00:20 pm
Añadiendo al mmp de SInstall para que genere un sisx Aquí están los UIDs a usar, que para un ejecutable de consola es 0x1000007A.

listado de capabilities para poner...

Tuesday, 16 September 2008, 1:23 pm
Instalado el SWInstallerLauncher SDK API plug-in para S60 SDK MR Lo he instalado haciendo lo siguiente:
$ cd /tmp/
$ mkdir t
$ cd t
$ unzip ~/S60_3rd_SDK_MR_API_Plug-In_Pack_v5_43.zip
$ unzip SWInstallerLauncher.ZIP
$ cd SWInstallerLauncher/
$ (tar -cf - epoc32/ ) | (cd /home/dario/symbian-sdks/s60_30/ & tar -xf - )
$ cd /tmp
$ rm -rf t
$ cd


Tuesday, 16 September 2008, 11:17:18 am
Instalación silenciosa de aplicaciones Página del Nokia Wiki con la descripción, Código de ejemplo: SilentInst.zip. Básicamente es hacer dos aplicaciones, la aplicación de usuario y otra para las actualizaciones. Cuando se ejecuta la de actualizar, se baja la nueva versión del .sisx y hace un SilentInstall (ver SilentInst/src/SilentInstEngine.cpp).

Aparte puede ser interesante una opción del pkg que es Running Executables on Install or Uninstall.

Cómo llamar a otros programas pasándoles parámetros y cómo recibirlos.

Desinstalando aplicaciones silenciosamente.

Para que esto funcione, se necesita el Trusted UI capability, e instalar el plug-in para el SDK: SW_Installer_Launcher_API.

Friday, 12 September 2008, 1:21:29 pm
ContextPhone sourcecode Resulta que hay un proyecto libre completo para Symbian S60 que usa comunicaciones TCP/IP y parece bien documentado. La úinica pega es que es para S60 1a y 2a Edicion (no para S60 3a edición que es lo que usamos nosotros). Es ContextPhone. Código de ejemplo de uso de sockets

Thursday, 11 September 2008, 2:55:09 am
Ejemplo de server socket usando RSocket aquí (último post)

Búsqueda: CActive RSocket.



Thursday, 11 September 2008, 2:39:42 am
Poniendo la aplicacion en 2o plano y volviendola a mostrar Artículo en NewLC, aunque para 2nd ed.
Otro artículo de lo mismo pero con mejor código de ejemplo: traer al frente (to foreground).

Wednesday, 10 September 2008, 10:42:42 pm
YAHOO! Encontrado como elegir el AP usando PIPS. Está explicado en Porting TightVNC to Symbian OS using PIPS (pdf) (HTML), en la página 24 en adelante.

Comentarios al artículo.
Descarga del VNC usando PIPS (y resto de cosas PIPS)

Al final es tansencillo como hacer lo siguiente, justo después de haber obtenido el fd con un socket() y antes de hacer el connect:



Wednesday, 10 September 2008, 10:26:44 pm
Poner el default access point Parece que sólo se puede hacer si usas RSockServ/RConnection/iSession. Post con código aquí. Thread con mucha información aquí. Artículos de Nokia sobre ello:
TSS000050 - How can I create an Internet connection without prompting a dialog?
TSS000203 - Using the HTTP Client API with RConnection.

Básicamente dicen que si el teléfono ya está conectado con otra aplicación (p.ej. VoIP), puedes usar esa conexión en tu aplicación con:
iConnection.Attach(connectionInfoPckg, RConnection::EAttachTypeMonitor); // RConnnection instance



Friday, 5 September 2008, 7:11:23 pm
Pasos para pedir un nuevo certificado
  1. Abres la máquina virtual WinXP
  2. Ejecutas el "Symbian Developer Request Wizard 2.0" del escritorio
  3. Cuando te pide el nombre, le das "c:\temp\sicosoft-with-pubidn.csr" (sustituye la "n" final por el número de pubid que es).
  4. Cuando te pida el ACS y privkey, coges los de TrustCenter que estan en Temp.
  5. Introduces los IMEIs que quieres
  6. Das a siguiente hasta que te dice que vayas a symbiansigned para pedir el developer certificate.
  7. Copias el .csr generado a dario@symbiandevel:
  8. En dario@symbiandevel, abres el firefox, y pones en la URL http://www.symbiansigned.com, esperas a que cargue la página y entras ne la cuenta de dariorodriguez@sicosoft.es (está memorizada en el firefox).
  9. Pinchas en la tab "My symbian signed"
  10. Pinchas en "OpenSigned->Request"
  11. Le pones el captcha y subes el fichero csr generado anteriormente
  12. Le das a Download; se bajara un sicosoft-with-pubidn.csr a ~/Desktop
  13. Lo copias a ~/
  14. Modificas el script dario@sybiandevel:workspace/compila.sh para que use el nuevo csr.
  15. Lo pruebas:
$ . ~/gnupoc/env.sh
$ cd workspace
$ rm -rf TCM
$ ./sincroniza.sh ; ./compila.sh
$ ~/e60_send.sh TCM/sis/TCM_S60.sisx
$ ~/e65m_send.sh TCM/sis/TCM_S60.sisx

Tuesday, 8 July 2008, 5:15:31 pm
Usar el teléfono GSM vía bluetooth con asterisk Antiguamente se hacía con chan_bluetooth. Actualmente se hace con el chan_cellphone integrado en asterisk 1.4.4+(pdf)

Actualizado el asterisk de symbiandevel a la versión 1.4.20 (backported de lenny) He recompilado la versión de lenny en etch para tener chan_cellphone (ya que en etch estaba con asterisk 1.2.x, que no soporta chan_cellphone). Los deb generados están en symbiandevel:/root/src.asterisk/

Por otro lado, en la página del paquete asterisk para debian hacen un listado del hardware compatible para esta versión (asterisk 1.4.20), que es:
  • All Wildcard (tm) ISDN PRI cards from Digium (http://www.digium.com)
  • HFC-S/HFC-4S-based ISDN BRI cards (Junghanns.NET, beroNet, Digium etc.)
  • All TDM (FXO/FXS) cards from Digium
  • Various clones of Digium cards such as those by OpenVox
  • Xorcom Astribank USB telephony adapter (http://www.xorcom.com)
  • Voicetronix OpenPCI, OpenLine and OpenSwitch cards
  • CAPI-compatible ISDN cards (using the add-on package chan-capi)
  • Full Duplex Sound Card (ALSA or OSS) supported by Linux
  • Tormenta T1/E1 card (http://www.zapatatelephony.org)
  • QuickNet Internet PhoneJack and LineJack (http://www.quicknet.net)

NOTA: Según Esta página, chan_modem-i4l (disponible en asterisk 1.4.x y superior) soporta tarjetas ISDN pasivas que usen el módulo hisax de isdn4linux (como las que usamos en SICO). Eso sí, tocará recompilar asterisk, ya que dicho módulo está desactivado por defecto en Debian

Thursday, 3 July 2008, 7:16:21 pm
Teléfonos configurados en el asterisk de symbiandevel
NúmeroDescripción
11el twinkle arrancado desde dario@symbiandevel
12el e60 (o el twinkle arrancado desde dario@seraphim_etch)
510Echo/loopback test
30000Voicemail

Thursday, 3 July 2008, 6:37:22 pm
He configurado el e60 para que se conecte con el asterisk de symbiandevel Siguiendo este howto - SIP with Nokia E60 and Asterisk.

Wednesday, 2 July 2008, 7:18:32 pm
Configurar un madwifi como AP para las pruebas con asterisk Usando una tarjeta atheros, se puede instalar el soporte madwifi en debian, y luego activar el modo ap (gentoo-wiki) (otro howto pero con ubuntu). NOTA: esto lo he hecho en symbiandevel. Después he activado wep128.

Friday, 27 June 2008, 6:29:31 pm
Mandar cosas con un cliente SIP CLI Resulta que el SIPSAK sólo admite mandar cadenas de texto, y no consigo verlas en el twinkle. Hay una alternativa, que es realizar llamadas de voz. Según este thread, el pjsua sí que permite mandar mensajes de voz. Además PJSUA/PJSIP tiene incluso bindings para TCL!.
Tengo compilado el pjsua en el chroot de etch en seraphim, en /home/metro/src.pjsua/pjproject-0.8.0/pjsip-apps/bin. He hecho ahí un enlace simbólico de pjsua al nombre real que tiene dicho ejecutable ;-).

Wednesday, 25 June 2008, 4:42:45 pm
Configurando un asterisk en symbiandevel He instalado el paquete asterisk y seguido los pasos de este tutorial. Otra gúia que tiene buena pinta: Getting started with asterisk.
Update: Probado con el cliente Twinkle. Está configurado e instalado tanto en dario@symbiandevel como en el chroot de etch en seraphim.

Friday, 20 June 2008, 6:20:03 pm
Simular pulsaciones de teclas Se hace con lo siguiente (más información aquí): SimulateKeyEvent(). ADemás hay que habilitar en el MMP la capability SW Event.

Por otro lado, para capturar la tecla Ok dentro del listbox, hay que hacerlo de la manera que explican aquí. Básicamente:
AppView debe ser:
class mycontainer1 : public CCoeControl, MCoeControlObserver, MEikListBoxObserver
{
.
.
.
CEikTextListBox mylistBox;
}

TKeyResponse mycontainer1::OfferKeyEventL(const TKeyEvent& keyEvent, TEventCode type)
{
if (type != EEventKey)
return EKeyWasNotConsumed;

switch (keyEvent.iCode)
{
case EKey0:
iEikonEnv->InfoMsg(_L("hello!!"));
break;
default:
return mylistBox->OfferKeyEventL(keyEvent, type);
}
return mylistBox->OfferKeyEventL(keyEvent, type);
}




Wednesday, 18 June 2008, 7:33:18 pm
Instrucciones para compilar TCM en symbiandevel
1. Entras como dario en symbiandevel
2. Instalas las variables de entorno
$ . ~/gnupoc/env.sh
2. Cambias al directorio workspace
$ cd workspace
3. Borras el directorio del TCM para asegurarte que vas a coger las ultimas versiones de todo
$ rm -rf TCM
4. Obtienes los fuentes que hay en salchicha (los fuentes siempre se editan en dario@salchicha:~/Programacion/proyectos/sico-tcm/actual ) y compilas
$ ./sincroniza.sh ; ./compila.sh
5. Subes la aplicación a los teléfonos por bluetooth (tienes que tener activado bluetooth en los teléfonos):
$ ~/e60_send.sh TCM/sis/TCM_S60.sisx
$ ~/e65m_send.sh TCM/sis/TCM_S60.sisx

Y en los teléfonos abres el mensaje que les ha llegado por bluetooth para instalar las aplicaciones.

Wednesday, 18 June 2008, 4:42:07 pm
Ya funciona el compilar directamente en symbiandevel sin usar el windows virtual Para más información ver las instrucciones. Básicamente es:
$ . ~/gnupoc/env.sh
$ cd ~/symbian-sdks/s60_30/s60ex/helloworldbasic/group
$ bldmake bldfiles
$ abld build gcce urel
$ cd ../sis
$ makesis helloworldbasic_gcce.pkg helloworldbasic.sis

Y ya está. Para firmarlo:
$ signsis helloworldbasic.sis helloworldbasic.sisx ~/sicosoft-with-pubid.cer ~/TrustCenter-Symbian-Sicosoft.pfx.key

NOTA: Para que funcione eso mismo para el TCM
1. He tenido que editar el gcce.make comentando todas las entradas de _help
2. He tenido que hacer enlaces simbólicos de algunos .h en ~/symbian-sdks/s60_30/epoc32/include para que tuvieran también la versión "mixed-case" que espera el TCM. p.ej.:
$ ln -s etel3rdparty.h Etel3rdParty.h

Wednesday, 18 June 2008, 4:31:06 pm
Instalado el rsync en la máquina virtual windows y en salchicha Es para sincronizar de salchicha al windows el directorio
 salchicha:/home/dario/Programacion/proyectos/sico-tcm/actual/TCM

En el windows hay un script llamado

C:\Symbian\Carbide\workspace\copia-de-salchicha.bat

que hace físicamente la copia.

Friday, 13 June 2008, 6:44:41 pm
Otra vuelta a compilar en Linux: updated gnupoc http://www.martin.st/symbian/ Symbian development on Linux and OS X

Friday, 16 May 2008, 5:59:28 pm
Convertir el certificado pfx a cer/key que necesitas para symbian Se hace de la siguiente manera:

$ openssl pkcs12 -in TrustCenter-Symbian-Sicosoft.pfx -nokeys -clcerts -out TrustCenter-Symbian-Sicosoft.pfx.cer
$ openssl pkcs12 -in TrustCenter-Symbian-Sicosoft.pfx -nocerts -out TrustCenter-Symbian-Sicosoft.pfx.key.ossl -nodes
$ openssl pkcs8 -in TrustCenter-Symbian-Sicosoft.pfx.key.ossl -inform PEM -topk8 -out TrustCenter-Symbian-Sicosoft.pfx.key -outform PEM -nocrypt


NOTA: Es importante poner password al certificado .key, ya que si no, el programa "Symbian Developer Request Wizard 2.0" da un fallo al intentar generar el documento (exactamente dice "Sorry, there were problems processing your Symbian Developer Certificate Request file").


Thursday, 8 May 2008, 7:09:45 pm
Sobre SIP Curiosamente, hay algo de información sobre los protocolos de anunciación de SIP en la FAQ del servidor de audio PulseAudio:
What is this RTP/SDP/SAP thing all about?

RTP is the Realtime Transfer Protocol. It is a well-known protocol for transferring audio and video data over IP. SDP is the Session Description Protocol and can be used to describe RTP sessions. SAP is the Session Announcement Protocol and can be used to announce RTP sessions that are described with SDP. (Modern SIP based VoIP phones use RTP/SDP for their sessions, too)
All three protocols are defined in IETF RFCs (RFC3550, RFC3551, RFC2327, RFC2327). They can be used in both multicast and unicast fashions. PulseAudio exclusively uses multicast RTP/SDP/SAP containing audio data.



Wednesday, 7 May 2008, 4:15:53 pm
Instalar un certificado en el IE Herramientas-> Opciones de Internet-> Contenido-> Certificados->
Importar-> Siguiente-> Se introduce el archivo .pfx que se ha exportado antes en otro ordenador-> Se intoduce la clave y se le dice que es exportable y ya está.

Para el FireFox 2.x Si es Windows, en Herramientas->Opciones; si es Linux es en Edit->Preferences. A partir de ahí: Avanzado-> Cifrado -> Ver Certificados-> Importar.

Friday, 11 April 2008, 5:44:50 pm
Creando un diálogo de elección de subsistema: NewLC: Creating a CAknSettingItemList in a Dialog.



Friday, 11 April 2008, 5:39:47 pm
Manera cómoda de pasar de un string tipo C a un descriptior TBuf<n> Se hace de la siguiente manera:
char TempStr[128];
sprintf(TempStr,"%i\t%s\t%s",1,"Cadena","Descripcion");
TPtrC8 ptr(reinterpret_cast<const TUint8>(TempStr));
TBuf<256> buffer;
buffer.Copy(ptr);
Y buffer ya se puede usar en donde necesitabas un descriptor, p. ej.:
CDesCArray *array = static_cast<CDesCArray *>(iListBox->Model()->ItemTextArray());
array->Reset();
array->AppendL(buffer);
iListBox->HandleItemAdditionL();
iListBox->SetCurrentItemIndex(0);
SizeChanged();

Wednesday, 9 April 2008, 6:24:59 pm
Para comprender mejor Symbian OS: Symbian OS Design Faults.

Monday, 31 March 2008, 5:08:45 pm
Symbian codes Obtenidos de aquí:
DatoCódigoDetalles
IMEI*#06#XXXXXX (TAC, Type approval code) XX (FAC, Final assembly code) XXXXXX (SNR, Serial number) X (SP, Spare)
Modelo/Firmware*#0000#Modelo, Versión y fecha de firmware
Format!*#7370# o bien *#res0#Formateo completo del teléfono (borra todo). El PIN queda 12345
Reset*#7780#Borra la configuración preservando casi todos los datos. El PIN queda 12345
Borrar Monedero ("Wallet")*#7370925538# o bien *#res0wallet#Borra todo en el monedero ("wallet"), para el caso de que olvides la clave
Tiempo de vida ("lifetime timer")*#92702689# o bien *#war0anty#Sólo funciona en algunos modelos (no en los muy antiguos y en los modenos sólo si es un equipo de pruebas de campo)
Bt MAC*#2820# o bien *#bta0#Muestra la MAC Bluetooth
WLAN MAC*#62209526# o bien *#mac0wlan#Muestra la MAC WLAN
Fail-safe Format[Green]+[def3]+[*+]Formateo a prueba de fallos (si el teléfono no llega a arancar o el formateo normal no funciona)

Wednesday, 19 March 2008, 7:15:21 pm
Crear menús dinámicos Del wiki de nokia: Changing the menu; hiding/showing entries y en Adding menu items dynamically.

Wednesday, 19 March 2008, 6:03:46 pm
Cambiar de forma dinámica el título (Title pane/status pane) de la app Aquí hay un thread explicándolo

Tuesday, 18 March 2008, 6:50:36 pm
Ejemplo completo de cómo crear un CEikEdwin Aquí.

Monday, 17 March 2008, 7:10:24 pm
Poniendo varios elementos y calculando su posición Aquí hay código de ejemplo:
void CVersificatorContainer::SizeChanged()
{
    TRect rect = Rect();
    TSize size = TSize(rect.Size().iWidth, 40);
    // TPtrC text1((iLabel->Text()));
    iTitleLabel->SetExtent( TPoint(0, 10), size);
    // TPtrC text2((iToDoLabel->Text()));
    iAlbumLabel->SetExtent( TPoint(0, 50), size);
    //iToDoLabel->SetExtent( TPoint(10,30), iToDoLabel->CalcMinimumSize(iToDoLabel->Text()));
    iArtistLabel->SetExtent( TPoint(0, 90), size);
}


Monday, 17 March 2008, 5:15:03 pm
Equipo SIP de IG Me han abilitado el siguiente equipo/centralita asterisk con acceso desde InterNet:
IP213.167.227.40 ifon1.infoglobal.es
PuertosSIP/tcp: 5060
SIP/udp: 5060
RTP:10000, 20000
Datos de conexión del cliente:
Clienteusuariopassworddominio registrosip uri
UNIX101*DM1pwdinfoglobal.essip:101*DM1@ifon1.infoglobal.es
Teléfono100*DM1pwdinfoglobal.essip:100*DM1@ifon1.infoglobal.es
NOTA: si pide usuario de dominio o algo así, es el mismo
NOTA2: El contacto para cosas de telefonía en IG es Jose Luis Gómez 660.904.920
NOTA3: El contacto para cosas de redes es Juan Ramón.

Tuesday, 11 March 2008, 11:20:02 am
C++ Refresher http://www.parashift.com/c++-faq-lite/ ya uqe al fin y al cabo, mi C++ es de tiempos del draft (y las STL las estudié como un añadido de HP/SGI, ni siquiera formaban parte del compilador...). Parece que al menos un poquito sí que ha cambiado ;-).

Tuesday, 4 March 2008, 9:09:27 am
Artículo: Cómo funcionan las syscall en Symbian Symbian OS exec calls. Como lectura complementaria: PDF: Introducing EKA2 (EPOC Kernel Architecture 2), en donde explican terminología como: "immediate deferred function calls (IDFCs)" (bottom-half handler en linux).

Tuesday, 4 March 2008, 9:03:23 am
Artículo: Skin Support En NewLC.com: Enable Skin support in your Symbian OS applications.

Friday, 29 February 2008, 8:35:09 am
Artículo: arrancar un programa al recibir y abrir un archivo el inbox En NewLC.com: Launching an application on a file arriving into the Inbox. Incluye ejemplo completo de creación y uso de un ActiveObject. Además, se muestra que los ActiveObjects disponen de un puntero al CAknAppUi-derived class:
void CMyLaunch::RunL () {
    CMyAppUi* MyAppUi = (CMyAppUi*) iAvkonAppUi;
    ProcessTheFileAsYouPlease (MyAppUi->ImportFile);
}


Friday, 29 February 2008, 8:28 am
Configurar SIP en S60 3rd y Asterisk (ejemplo con E60) En NewLC.com Using SIP with Nokia Series60 and Asterisk

Friday, 29 February 2008, 8:00:12 am
Firmando ejecutables desde el IDE Se puede hacer (aunque sólo para un teléfono). Está en la "Carbide Build Configurations sheet".

Friday, 29 February 2008, 7:56:56 am
On-device debugging artículo. El problema es que requiere una de las versiones de pago del IDE (bien el Developer o el Pro).

Friday, 29 February 2008, 7:37:10 am
Sobre el Startup List API: cómo detectar si la aplicación ha sido arrancada con él En NewLC.com: How to detect if an application is launched by user or the startup list.

Thursday, 28 February 2008, 10:40:55 am
Cómo funcionan los observers en Symbian En NEwLC.com: http://www.newlc.com/Observer-Pattern-in-Symbian.html
Ampliado en Implementation of Observer Pattern Using Symbian View+Container And ActiveObject (recomendable leer primero el tutorial básico y luego éste).

Thursday, 28 February 2008, 10:19:16 am
Manera "definitiva" de obtener el IMEI en S60 3rd Ya que la manera de Symbian 7.x no funciona y el de UIQ... bueno, pues que es para UIQ. Retrieving IMEI, IMSI, Network Info (Cell Id, Location Code) on 3rd Edition.

Thursday, 28 February 2008, 9:59:52 am
Quitando warnings del SDK Aplicado este artículo: How to avoid the "enumeral mismatch" error in eikmenup.h (línea 183 de eikmenup.hen S60 3rd)y puesto el enter final en los ficheros que protestaba por ello.

Wednesday, 27 February 2008, 9:24:28 am
Artículo: 5 Most common mistakes in Symbian programming: En NewLC.com: Top 5 common mistakes to cause memory leaks in Symbian C++ applications. La parte más importante es:
  • Se usan referencias en vez de punteros cuando el dato pasado es "not-owned by the receiving function/class".

Artículo: Common misuse and abuse of Symbian OS En NewLC.com: Common mis-use and abuse of Symbian OS. Incluye:
  • Active Objects (clases que hacen procesamiento asíncrono).
    • Quizás la más importante es que hay que llamr a instanciaactiveobject.Cancel() antes de destruirlo, y no hace falta comprobar isActive() antes de hacerlo, ya que eso lo comprueba él mismo.
    • Aparte de eso, si vas a usar Cancel(), tienes que escribir el código de DoCancel() que haga la cancelación (al fin y al cabo, es un objeto que tú has escrito).
    • Para que el ActiveObeject funcione, hay que tener un ActiveScheduler. Las aplicaciones con UI usan el del UI, pero en los ejecutables hay que inicializarlo explícitamente.CActiveScheduler* scheduler = new CActiveScheduler; CActiveScheduler::Install(scheduler); CMyActive* active = CMyActive::NewL(); active->DoStuff(); CActiveScheduler::Start();. El CActiveScheduler::Start(); es equivalente al main_event_loop de motif o de gtk+.
  • Cuándo debe devolver una función en vez de un TDesC/TDes, un TPtrC/TPtr.
  • El parámetro de construcción de las arrays es la granularidad (de cuántos en cuántos hace "malloc"). p.ej. CBufBase buffer = CBufFlat::NewL(5);



Monday, 25 February 2008, 11:34:10 am
Artículo: How to create a static array of literals En NewLC.com: How to create a static array of literals:
_LIT(KSomeText,"Hello");
_LIT(KMoreText,"World");

const TPtrC gStringArray[] =
{
   KSomeText(),
   KMoreText(),
   ...
};

NOTA: Esto es uno de los muchos artículos de newlc tutorials section.

Friday, 22 February 2008, 10:32:26 am
Sobre message box, ontop windows et al Interesante thread sobre estos temas. Básicamente:
  • Each CCoeControl-derived class can handle at most 1 window.
  • The CCoeControl is always attached to one window, be it the one it owns or if it doesn't have a window, to the parent one.
  • Thus, each CCoeControl has a window handle, and it's used to find the right CCoeControl to handle the redraw.

Además es interesante esta otra thread sobre drawing dynamically updated controls:
  • If you add controls dinamically to your container, you have to call DrawDeferred() after it (and they must have been ActivateL()'d).

Thursday, 21 February 2008, 11:08:59 am
Uso de una listbox Está aquí (sólo le faltan los \t).

Tuesday, 19 February 2008, 11:07 am
Resumen de las clases de una aplicación gráfica Symbian S60 Es la siguiente tabla (lo siento, en inglés para que sea más coherente con los nombres de clases, sorry!):
Parent classDerived class name (new/old)It does..
CCoeControl
MCoeControlObserver
View/Container+ConstructL(): construct the controls. Instantiate all the controls and assign them to a member variable. Asign them to this window with iControlName->SetContainerWindowL(this); iControlName->SetRect(Rect());. Finally, activate the window with ActivateL();
+Draw():Draw the background of the view area (it may be overwritten if you put controls, especially with Styled ones, as they replicate the wallpaper).

example
CAknAppUiUi/Ui+ConstructL(): initializes an instance of the CCoeControl-derived class, and calls CCoeControl-derived->SetMopParent(this) so that the CCoeControl-derived instance can forward the keys to the CAknAppUi-derived class. Then calls the CCoeControl-derived->ConstructL(this,flags) of the CCoeControl-derived class. Finally, it calls this::AddToStackL(CCoeControl-derived instance) to receive key events (all controls with input events must be added to the stack).
+HandleKeyEventL(): receives the keys pressed; useful to forwarding them to the corresponding control (widget)
+HandleCommandL(): receives the command events (e.g. from a contex menu), as defined in the resources
CAknDocumentDocument/Document+CreateAppUiL(): returns a new instance of the CAknAppUi-derived class
+Initializes and holds instances of model classes that hold the application state and are able to load/save that state to/from disk
CAknApplication(App)lication/(App)+Base class has main loop
+CreateDocumentL(): returns a new instance of the CAknDocument-derived class
+AppDllUid(): Returns the UID3
(none; main)(none; main)+NewApplication(): returns a new instance of the CAknApplication-derived class
+E32Main(): calls EikStart::RunApplication(NewApplication);

Bear in mind that although the classes in this table are called (or more accurately, created) from bottom to top in this table, the calling instance is saved in the called instance member data, so instances of classes that are in the top positions of this table can access the instances in the bottom positions.

Tuesday, 19 February 2008, 10:35:31 am
Problemas con las teclas: no llegan al listbox No soy el único (con código con el error pero sin solución incluída).

Tuesday, 19 February 2008, 9:11:58 am
Haciendo UIs desde Symbian exe s (en vez de dlls) Artículo del wiki: Mostrando controles en Symbian exe programs

Monday, 18 February 2008, 11:28:10 am
Uso de HandleKeyEvent En este artículo:

TKeyResponse CTestAppUi::HandleKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
{
// si no se van a tratar...
return EKeyWasNotConsumed;
}

//...
if (aType == EEventKey)
{
switch (aKeyEvent.iScanCode)
{
case EStdKeyLeftArrow:
iAppContainer->ToggleColour(KRgbCyan);
return EKeyWasConsumed;
break;
}
}
//...

Tabla de teclas:
Números,# y *Se devuelven tal cual
JoystickEKeyLeftArrow
EKeyDownArrow
EKeyUpArrow
EKeyRightArrow
EKeyOK //pulsación de joystick
EspecialesEKeyPhoneSend // teléfono verde
EKeyPhoneEnd // teléfono rojo
EKeyGripOpen //evento de apertura de teclado
EKeyGripClose //evento de cierre de teclado

Monday, 18 February 2008, 11:13:17 am
Cómo obtener el IMEI del teléfono Resulta ser muy sencillo obtener el IMEI:
Librerías requeridasLIBRARY plpvariant.lib
Ficheros de cabecera#include "plpvariant.h"
CódigoTPlpVariantMachineId id;
PlpVariant::GetMachineIdL(id);

TBuf<KMaxPlpVariantMachineIdLength> iIMEI;
iIMEI = id;

iEikonEnv->AlertWin(_L("IMEI:"),iIMEI);
NOTA: OTro artículo para obtenerlo en UIQ3.0

Monday, 18 February 2008, 10:37:24 am
Conectándose a Internet sin poner un diálogo de conexión En la lista de temas (KB Technical Solutions) hay una página que indica cómo hacer una conexión a internet sin sacar un diálogo de conexión (sample code). Requiere el "IAP ID" del access point que va a ser usado, lo cual no es fácil (debería ser posible sacarlo buscando por SSID nuestro AP de la lista de hotspots). Por otro lado, deberíamos estar conectados gracias a VoIP (pero en la demo no tendremos VoIP...).

Monday, 18 February 2008, 10:06:09 am
Dibujando un fondo detrás de la listbox Hay un howto aquí. Básicamente es hacer una clase que hereda de la listbox, en la que se sustituye el método draw por uno nuevo, y luego se llama al antiguo.

NOTA: para el array de escrings, aquí hay código de cómo hacerlo.

Tuesday, 12 February 2008, 8:37:08 am
SIP desde línea de comandos: SIPSAK El SIPSAK (SIP Swiss Army Knife) es un cliente SIP en línea de comandos para desarrolladores y administradores de aplicaciones SIP. Entre otras cosas, puede simalar llamadas con el modo "usrloc". También puede mandar mensajes SIP.

Friday, 8 February 2008, 7:28:01 pm
Generación de iconos SVG desde el inkscape Los pasos a seguir son:
  1. Haces el icono normalmente con el inkscape
  2. Lo pasas por la script ./svg2s60.pl
  3. Lo pasas por el SVG2SVGT del XP emulado
  4. Quitas los "mm" de la parte que dice width="..." height="..."
  5. Añades a la línea que empieza por "<svg " un "viewBox="150 0 600 700">" al final.
  6. Lo abres con el notepad y el squiggle, y vas modificando los valores del viewbox hasta que cuadre
  7. Lo metes el en teléfono y cruzas los dedos para que no haya perdido ningún elemento...

¡ATENCION! No se pueden usar curvas bezier en los polígonos (si las usas, TODO el polígono quedará sin ser dibujado).
¡ATENCION! No soporta elipses, pero si las conviertes en "paths" sí que aparecen.
¡ATENCION! No parece soportar degradados no lineales (p.ej. puntuales/"esféricos")


Wednesday, 6 February 2008, 6:48:58 pm
Uso de la pantalla directamente En esta thread comentan que se puede usar la pantalla directamente usando este ejemplo (bitblits), o siguiendo el código expuesto ahí, incluso con memcpy... Por otro lado, indican al final del thread cómo modificar este otro ejemplo de acceso directo para que funcione en teléfonos rgb888.

Monday, 4 February 2008, 6:11:30 pm
Para compilar y poner las cosas en los teléfonos Ups, parece que esto no lo había documentado, y no es presisamente intuitivo. Aquí va:

  1. En el Carbide editas tu proyecto, una vez que hayas terminado la edición, salvas todos los ficheros
  2. Proyect> active build>phone
  3. Proyect>Clean...
  4. Selecccionas sólo tu proyecto y "Start a build inmediatly", luego das al Ok
  5. Compruebas en la ventana Problems que sólo hay warnings, que no haya errores
  6. Abres en una ventana el directorio sis de tu proyecto (C:\Symbian\Carbide\workspace\nombreproyecto\sis) en el explorador
  7. Abres otra ventanas en \Temp
  8. Copias el sis en \Temp
  9. Abres un terminal en \Temp
  10. Ejecutas:
    C:\Temp>sign nombre_S60_3_X_v_1_0_0.sis
  11. Abres el FTP a symbiandevel
  12. Copias los dos .sis generados al home de dario en symbiandevel
  13. En symbiandevel, haces:
    dario@symbiandevel:~$ ./e60_send.sh e60_nombre_S60_3_X_v_1_0_0.sis ; ./e65_send.sh e65_nombre_S60_3_X_v_1_0_0.sis

NOTA: Para que pueda mandar las aplicaciones a los teléfonos estos han de estar encendidos (¡claro!) y con el bluetooth activado (el icono de la B, y te aseguras que Bluetooth esté activado (en modo fuera de línea)).

Monday, 4 February 2008, 5:40:50 pm
Generando svg-tiny (svgt)Resulta que hay una utilidad en el SDK de symbian para convertirlos (JRE 1.4), pero los svg de inkscape hay que preprocesarlos primero con http://gnugos60.blogspot.com/2007/02/inkscape-and-svg2svgt.html. Hay que tener instalada la JRE 1.4, y instala usando el instalador svg2svgtconverter.exe (que está en uno de los subdirectorios de \Symbian). Con eso instalado y el conversor puesto en UNIX ya se pueden hacer ficheros svg tiny.

Básicamente hay que hacer:
  1. Generar el .svg con el inkscape en dario@symbiandevel:graficos
  2. Ejecutar en dicho directorio:
    dario@symbiandevel:graficos$ ./svg2s60.pl < fichorig.svg > fichorig_tiny0.svg
  3. Copiarlo al WinXP emulado
  4. En el XP emulado, ejecutar el SVG2SVGT que has instalado antes y ponerle como ficheros a conbertir el fichorig_tiny0.svg y directorio de destino el gfx de tu proyecto
  5. Renombras el fichero generado a lo que realmente necesitabas y ya está :-).

NOTA: Algunas recomendaciones sobre SVG (no usar doctype, etc)
NOTA2: Sobre los gui apis en JavaME, incluyendo un ejemplo de SVG-Tiny. Para crear el SGV-Tiny han usado el Beatware Mobile Designer 2 2.0 (un poco caro, tiene eval de 30d).

Monday, 21 January 2008, 5:32:59 pm
Averiguando si soporta WLAN y saber la MAC Se puede consultar la MAC con lo siguiente:
==CUT===
There are one simple way to detect if phone supports WLAN. This is useful if your application only runs in a WLAN enabled phone:

A) Does the S60 3rd device have WLAN chip?
In /epoc32/include/featurediscovery.h file , the wlan key can be used to query for the feature.

/**
Device supports WLAN protocol.
*/
const TInt KFeatureIdProtocolWlan = 109;


B) and how to read the MAC address in S60 3rd edition devices:
http://www.forum.nokia.com/Technical...AC_address.htm
==CUT===

Monday, 21 January 2008, 5:28:58 pm
Detectando llamadas VoIP Resulta que el API de VoIP Nokia no es público, pero se puede acceder como mínimo a la configuración usando mensajes wbxml a la appid w9033...

Update: Sí, se pueden detectar las llamadas VoIP entrantes: detect incoming SIP call on nokia E65. El documento referenciado es Utilizing Nokia VoIP Client. Código (.zip).

Monday, 21 January 2008, 5:04:37 pm
Background apps Sí, se pueden hacer (usando .exe en vez de .app en Symbian pre-9, en 9.x todos son .exe). Si se necesita un UI, hay que hacer un .exe para el "background process" y un .app para UI, y se han de comunicar por IPC.

Para arrancar un .app desde un .exe se hace con el UID del .app.

Alternativamente, hay una manera de pasar una aplicación a backgorund: background app example (aunque no es el método recomendado).

Por último, para que la aplicación arranque automáticamente cuando se arranca el aparato: Recognizer/autostart;Watchdog + application start. Ejemplo. Alternativa (recomendada): Usar el System-on-boot API

Monday, 14 January 2008, 7:15:28 pm
Apuntes del Symbian_OS_Basics_Workbook_3_0_en.ps Es interesante recordar los siguiente:
Prefijos a los nombres de las clases
Txxxx: (T)ype, no pointers, usable in stack
Cxxxx: (C)alloc, use new (ELeave) with it.
Rxxxx: (R)esource/file/timer
Mxxxx: (M)essage interface, no member data, previously known as misin instead of interface.

Prefijos a los nombres de variables
axxxx: (a)rgument to function
ixxxx: (i)nternal member data of class
nadaxxxx: autovariable
Kxxxx: "(K)onstant" (const)
ANY_CAPITALxxxx: ??? global variable

Sufijos a las funciones miembro
xxxxD: issues (D)eletion of an object
xxxxL: function may (L)eave
xxxxC: adds an item to the (C)leanup-stack that the user of the function must Cleanupstack::Pop() elsewhere

Idioms
new (ELeave) TMyType: En Symbian, el operador new está "overloaded", y puede generar un Leave (además tiene un parámetro que hay que rellenar con el enum "ELeave").
User::LeaveNoMemory(), User::Leave(KErrNotFound) /* err32std.h */, User::LeaveIfNull(mypointer), User::LeaveIfError(errorfromsystemapi): ejemplos de provocar un Leave.
TRAP(_r,_s)/TRAPD(_r,_s): Es como el catch de ANSI C++ pero para los Leaves. En general no se recomienda usarlos (por defecto ante un error, el programa vuelve al estado inicial o similar --no queda muy claro en la doc.). TInt error; TRAP(error,FuncionL()); if(error!=KErrNone) /* hubo Leave */;
CleanupStack::PushL(myptr); CleanupClosePushL(myfd); CleanupStack::Pop(ignored), Cleanupstack::PopAndDestroy(ignored), CleanupStack::Pop(nitems,lastignored) Sirve para manejar el cleanupstack. PopAndDestroy es un hack que aprovecha que has metido la información necesaria para un delete/close para hacerlo y evitarte escribir una línea más. Y sí, el interfaz es incoherente porque CleanupClosePushL(myfd); no sigue la sintaxis CleanupStack::LoQueSea().
Two-phase Construct: constructor+ConstructL/ConstructLC(), wrapped in public static function NewL/NewLC() that returns a newly constructed object using the two-phase construct Vamos, que en vez de hacer "varptr=new (ELeave) CMyClass", se usa "varptr=CMyClass::NewL[C]()" para hacer uso del "two-phase construct". Implicaciones: las estructuras L sólo se pueden generar en el heap (no en la pila, por no poderse usar como autovariables por lo de llamar al ConstructL[C]; ahora bien, si se llamase "a mano" ¿funcionaría?). Como cosa curiosa, la norma de Symbian es declarar como private tanto el constructor como el ConstructL, de manera que haya que usar por el NewL[C] a la fuerza. Otra norma es que se es una clase que se va a usar para crear clases derivadas, no se debe incluir NewL[C] y en vez de ConstructL[C] se define BaseConstructL[C] (esto último no tiene mucha razón de ser, pudiendo acceder al ConstructL[C] del padre con un NombreClasePadre::ConstructL[C], pero bueno, habrá que respetarlo...).

Info adicional
(R) type classes usually work by returning ok/error results, while (C) type classes usually work by Leaving if there is an error: esto es porque sería muy incómodo tener que hacer un "trap harness" cada vez que vas a intentar acceder a un fichero por si no existe. Devolver error tiene ventajas para proceso inmediato, mientras que hacer Leaves tiene ventajas para proceso diferido. Se puede convertir un código de error en un Leave "enclosing the call into a User::LeaveIfError()".
El acceso a disco es conectándose al servidor de almacenamiento (!):
void DeleteFileL(const TDesc& aFileName)
  {
  RFS fs; // file server
  CleanupClosePushL(fs);
  User::LeaveIfError(fs.Connect());
  User::LeaveIfError(fs.Delete(aFileName));
  CleanupStack::PopAndDestroy(&fs);
  }

_UHEAPMARK / UHEAPMARKEND Son macros que comprueban que el heap está en el mismo estado de ocupación en los sitios marcados con la macro (si no lo está, core). Sirve para ayudar en la búsqueda de un memory leak (que se hacen aparentes porque al salir la aplicación, si la heap no está vacía (hay un memleak), da un core). Admiten "nesting".
User::Panic() Esto provoca un Panic, que es un core por excepción no manejada.


Otras cosas del tutorial Symbian_OS_Basics_Workbook_v3_0_en.pdf
pág 167: _LIT, TBuf, TBufC, TPtr, TPtrC, HBufC, TDesC, TDes.
pág 186: CCnvCharacterSetConverter, PrepareToConvertToOrFromL, ConvertFromUnicode/ConvertToUnicode.
pág 198: UI App startup sequence
pág 209: UI, Tratamiento de teclas en CMyAppUI::HandleKeyEventL() que devuelve EKeyWasConsumed/EKeyWasNotConsumed, etc.
pag 217: CCoeControl derivatves: the container (example); CountComoponentControls, ComponentControl,...

NOTA Lo que en el tutorial aparece como CMyAppContainer, en el codigo generado es nombreAppView.[ch]:CnombreAppView.
NOTA si no compila con un file io error pero todo parece estar bien, es que falta una libreria y no ha generado el ejecutable. tambien puede ser una funcion miembro no definida pero que si estaba en el prototipo o definicion de la clase, ya que esas no salen en el resumen de warnings pero si en la consola y hay que buscarlas entre tanta linea de compilacion.

Friday, 7 December 2007, 7:22:28 pm
Metiendo char* en el CleanupStack Según este post se hace así:

char *cadena=malloc(tam_cadena);
CleanupStack::PushL(TCleanupItem(free, cadena));
// ... some L calls
CleanupStack::PopAndDestroy(cadena);
// Note that the "free" operation needs to be a
// TCleanupOperation, i.e. taking a single void*
// parameter and returning nothing.


NOTA:malloc y free son las funciones correspondientes a la libc (lo digo por el free principalmente).
NOTA2: Ejemplo de uso de cadenas C y su conversión a cadenas Symbian (TBufC). Es un ejemplo curioso: obtiene la localización que manda la base en su broadcast a los teléfonos.


Friday, 7 December 2007, 6:04:59 pm
Problemas con el connect Al igual que a este usuario, connect me devuelve 13 (EACCES). La solución es añadir al .mmp:

 CAPABILITY NetworkServices

NOTA off-topic: Son muy interesantes las OpenC Developer Discussion Boards
Así he visto referencias a esta FAQ, p.ej: Se debe declarar la dependencia de P.I.P.S si es un programa OpenC

Friday, 7 December 2007, 4:42:12 pm
Sobre los String descriptors (HBufC y amigos) tutorial: Using Symbain OS String Descriptors, uso de AppendFormat. También son interesantes los siguientes artículos relacionados: Char & Descriptor conversion y Conversion between TPtrC and char*; nokia wiki: How to Convert TBuf to Char and Vice Versa.

Thursday, 22 November 2007, 4:16:10 pm
Para los problemas de teclado del vmware He seguido las instrucciones de esta página. Es decir, añadir al .vmx, si se usa un XFree86:
 xkeymap.usekeycodeMapIfXFree86 = true
O bien si es un VNC:
 xkeymap.usekeycodeMap = true

Update: Al final estoy editando el fichero /usr/lib/vmware/xkeymap/is104, que es el que está usando.
Update: Al final, lo más fácil es no usar un VNC y exportar el display directamente a salchicha, ya que si no tiene la extensión XKEYBOARD, hace cosas MUY raras; Xvnc no la tiene y por eso hacía esas cosas.

Friday, 16 November 2007, 6:31:52 pm
Installación de OpenC para Carbide 1.2 Lo explican en este thread.Básicamente es extraer el zip s60_openc_plugin.zip en c:\Symbian\9.1\S60_3rd . Aparte de eso, hay que instalar los sis de la carpeta s60opencsis (openc_glib (contiene la glib, es opcional), openc_ssl (libcrypt, libcrypto, libz y libssl), pips_s60_wp (es el requerido: libc, libm, libdl y libpthread); opcionalmente se puede instalar stdioserver (que porporcina un visualizador de stdout)) en el terminal.

Por otro lado, para que las aplicaciones encuentren los .h, hay que poner en todos los MMP:

SYSTEMINCLUDE \epoc32\include\stdapis

Curiosamente, se puede especificar que el pips_s60_wp.sis se incluya DENTRO de tu .sis, poniendo en la definición del paquete (lo que usa para gererar los sis):
...
...

Para los otros es de manera análoga (ver s60opencreleasenotes.txt).

Además, en uno de los .c (y sólo en uno) hay que añadir:

#ifdef __GCCE__
#include 
#endif

Wednesday, 17 October 2007, 7:29:06 pm
Notas sobre la asociación bluetooth Primero (para que funcione el obex_ftp -bt MAC fichero) hay que asociar el dispositivo. Para eso se sigue el tutorial. Básicamente:
  1. Se lanza el bluetooth-applet &
  2. Se lanza el bluetooth-properties y se pone que todo el nmundo le vea y acepte conexiones
  3. En el móvil se va a bluetooth, vínculos, buscar, seleccionamos el dispositivo. CUando nos pida una clave ponemos cualquiera (p.ej. 1234)
  4. En el PC damos un doble clicj en el icono del bluetooth (debería estar parpadeando) y ponemos la misma clave en la ventana que sale.
  5. Ya está. Ya se pueden mandar ficheros con obex_ftp :-). Para ver la MAC bluetooth, se hace con:
    $ dario@symbiandevel:~$ hcitool scan
Para un GUI ver este artículo

Wednesday, 17 October 2007, 6:17:53 pm
Notas sobre el certificado La clave es sicosoft, los imeis (*#06#) son:
ModeloIMEICodeMAC WiFiMAC Bt
E60356219/00/070369/0052432800:15:de:3e:0c:4100:12:d1:04:66:21
E65353261010133685053685000:19:79:44:de:5800:17:e4:dd:9e:f3
E65Metro353261010133735053685000:19:79:44:de:5d00:17:e4:dd:91:00
E65ig353261010133719-00:19:79:44:de:5b-

Para instrucciones sobre symbiansigned.com, ver este thread de cómo formar un sis este thread de cómo firmar un sis online (el método off-line ya no funciona sin comprar un publisher id...).

Wednesday, 10 October 2007, 6:19:01 pm
Haciendo que el Belkin USB funcione en Linux Resulta que su ID está mal en la BBDD de USB de linux, y hay que hacer lo siguiente:
 # echo blacklist pegasus >> /etc/modprobe.d/blacklist
 # modprobe hci_usb
 # echo hci_usb >> /etc/modules

Wednesday, 10 October 2007, 4:42:42 pm
Hacer el escritorio de XP usable Aquí hay enlaces a unas cuantas aplicaciones que lo permiten. Especialmente Virtual Dimension.

Thursday, 4 October 2007, 5:24:16 pm
Ya está instalado el carbide Y para finalizar la instalación dice:
Configuring environment for WINSCW command line builds
If you want to build for the emulator from the command line, run the tool from the start menu shortcut: Configure environment for WINSCW command line builds. It will setup the necessary environment variables. You do not need to do this if you only be building emulator targets (WINSCW) from the IDE.


Descripción del proyecto


Hacer la aplicación de TCII basada en listas para el E60 de Nokia (teléfono Symbian OS 9.0, S60 3rd edition).

El entorno de desarrollo es el Carbide C++ 1.2 Express, y corre sobre máquina emulada (10.0.100.6 desde salchicha) en symbiandelvel (10.0.100.5 desde salchicha). Paea la próxima vez se puede intentar instaklar XP usando nLite>http://forum.eeeuser.com/viewtopic.php?id=1923, pero por ahora valdrá con lo que hay O:-).

Para información sobre el teléfono: página del swiki sobre teléfonos factibles para el proyecto (incluye enlaces de desarrollo)>http://3.0.1.45:8000/testing/124

Para el tutorial: http://www.symbiantutorial.org/symbian-tutorial/

Las instruccione spara compilar y subir las aplicaciones están en Wednesday, 18 June 2008, 7:33:18 pm