ST / Mbed 2 deprecated NFC01A1_Demos

Dependencies:   NDefLib X_NUCLEO_NFC01A1 mbed

Fork of X-MBED-NFC1 by Giovanni Visentini

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SampleAsync_writeAndChangeAll.cpp Source File

SampleAsync_writeAndChangeAll.cpp

Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file       SampleAsync_writeAndChangeAll.cpp
00004   * @author     ST / Central Labs
00005   * @date       03 Dic 2015
00006   * @brief      This demo write an ndef message different records, when the user press the buttun
00007   *             read the tag, change some data and write it again
00008   ******************************************************************************
00009   *
00010   * COPYRIGHT(c) 2015 STMicroelectronics
00011   *
00012   * Redistribution and use in source and binary forms, with or without modification,
00013   * are permitted provided that the following conditions are met:
00014   *   1. Redistributions of source code must retain the above copyright notice,
00015   *      this list of conditions and the following disclaimer.
00016   *   2. Redistributions in binary form must reproduce the above copyright notice,
00017   *      this list of conditions and the following disclaimer in the documentation
00018   *      and/or other materials provided with the distribution.
00019   *   3. Neither the name of STMicroelectronics nor the names of its contributors
00020   *      may be used to endorse or promote products derived from this software
00021   *      without specific prior written permission.
00022   *
00023   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00024   * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
00026   * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
00027   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00028   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00029   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00030   * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
00031   * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00032   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033   *
00034   ******************************************************************************
00035   */
00036   
00037 #include "mbed.h"
00038 
00039 #include "NDefLib/NDefNfcTag.h"
00040 
00041 #include "NDefLib/RecordType/RecordAAR.h"
00042 #include "NDefLib/RecordType/RecordSMS.h"
00043 #include "NDefLib/RecordType/RecordGeo.h"
00044 #include "NDefLib/RecordType/RecordURI.h"
00045 #include "NDefLib/RecordType/RecordMail.h"
00046 #include "NDefLib/RecordType/RecordText.h"
00047 #include "NDefLib/RecordType/RecordMimeType.h"
00048 #include "NDefLib/RecordType/RecordVCard.h"
00049 #include "NDefLib/RecordType/RecordWifiConf.h"
00050 
00051 #include "XNucleoNFC01A1.h"
00052 
00053 /**
00054  * Shift the led status between the 3 leds.
00055  */
00056 static void shift_led(DigitalOut &led1,DigitalOut &led2,DigitalOut &led3){
00057     const uint8_t prevLed1=led1;
00058     const uint8_t prevLed2=led2;
00059     const uint8_t prevLed3=led3;
00060     led1=prevLed3;
00061     led2=prevLed1;
00062     led3=prevLed2;
00063 }
00064 
00065 /**
00066  * Print in the console some data about the record.
00067  * @param r Record to print.
00068  */
00069 static void print_record(NDefLib::Record *const r){
00070     using namespace NDefLib;
00071     switch(r->get_type()){
00072         case Record::TYPE_TEXT: {
00073             const RecordText *const temp = ( RecordText* )r;
00074             printf("Read Text: %s\r\n",temp->get_text().c_str());
00075             break; }
00076         case Record::TYPE_AAR:{
00077             const RecordAAR *const temp = ( RecordAAR* )r;
00078             printf("Read ARR: %s\r\n",temp->get_package().c_str());
00079             break; }
00080         case Record::TYPE_MIME:{
00081             const RecordMimeType *const temp = ( RecordMimeType* )r;
00082             printf("Read mimeType: %s\r\n",temp->get_mime_type().c_str());
00083             printf("Read mimeData: %s\r\n",
00084                     std::string((const char*)temp->get_mime_data(),
00085                             temp->get_mime_data_lenght()).c_str());
00086             break;}
00087         case Record::TYPE_URI:{
00088             RecordURI *const temp = (RecordURI*)r;
00089             printf("Read uriId: %d\r\n",temp->get_uri_id());
00090             printf("Read uriType: %s\r\n",temp->get_uri_type().c_str());
00091             printf("Read uriContent: %s\r\n",temp->get_content().c_str());
00092             break;}
00093         case Record::TYPE_URI_MAIL:{
00094             const RecordMail*const temp = (RecordMail*)r;
00095             printf("Read Dest: %s\r\n",temp->get_to_address().c_str());
00096             printf("Read Subject: %s\r\n",temp->get_subject().c_str());
00097             printf("Read Body: %s\r\n",temp->get_body().c_str());
00098             break;}
00099         case Record::TYPE_URI_SMS:{
00100             const RecordSMS*const temp = (RecordSMS*)r;
00101             printf("Read number: %s\r\n",temp->get_number().c_str());
00102             printf("Read message: %s\r\n",temp->get_messagge().c_str());
00103             break;}
00104         case Record::TYPE_URI_GEOLOCATION:{
00105             const RecordGeo*const temp = (RecordGeo*)r;
00106             printf("Read lat: %f\r\n",temp->get_latitude());
00107             printf("Read long: %f\r\n",temp->get_longitude());
00108             break;}
00109         case Record::TYPE_MIME_VCARD:{
00110             const RecordVCard *const temp = (RecordVCard*)r;
00111             printf("Read Name: %s\r\n",(*temp)[RecordVCard::NAME].c_str());
00112             printf("Read Mail: %s\r\n",(*temp)[RecordVCard::EMAIL_WORK].c_str());
00113             printf("Read ORG: %s\r\n",(*temp)[RecordVCard::ORGANIZATION].c_str());
00114             break;}
00115         case Record::TYPE_WIFI_CONF:{
00116             const RecordWifiConf *const temp = (RecordWifiConf*)r;
00117             printf("Nework Name: %s\r\n",temp->get_network_ssid().c_str());
00118             printf("Nework Key: %s\r\n",temp->get_network_key().c_str());
00119             printf("Nework Auth: %X\r\n",temp->get_auth_type());
00120             printf("Nework Enc: %X\r\n",temp->get_encryption());
00121             break;}
00122         case Record::TYPE_UNKNOWN:{
00123             printf("Unknown record\r\n");
00124             break;}
00125     }//switch
00126 }//printRecord
00127 
00128 /**
00129  * Change the record content.
00130  * @param r Record to change.
00131  */
00132 static void change_record(NDefLib::Record const* r){
00133     using namespace NDefLib;
00134     switch(r->get_type()){
00135         case Record::TYPE_TEXT: {
00136             RecordText *temp = (RecordText*)r;
00137             temp->set_text("Hello");
00138             break; }
00139         case Record::TYPE_AAR:{
00140             RecordAAR *temp = (RecordAAR*)r;
00141             temp->set_package("set Package Ok");
00142             break; }
00143         case Record::TYPE_MIME:{
00144             RecordMimeType *temp = (RecordMimeType*)r;
00145             temp->copy_mime_data((const uint8_t *)"String2",sizeof("String2"));
00146             break;}
00147         case Record::TYPE_URI:{
00148             RecordURI *temp = (RecordURI*)r;
00149             temp->set_content("mbed.com");
00150             break;}
00151         case Record::TYPE_URI_MAIL:{
00152             RecordMail *temp = (RecordMail*)r;
00153             temp->set_to_address("newMail@st.com");
00154             temp->set_subject("tag change");
00155             temp->set_body("read/change Works!");
00156             break;}
00157         case Record::TYPE_URI_SMS:{
00158             RecordSMS *temp = (RecordSMS*)r;
00159             temp->set_message("Message Change");
00160             temp->set_number("0987654321");
00161             break;}
00162         case Record::TYPE_URI_GEOLOCATION:{
00163             RecordGeo *temp = (RecordGeo*)r;
00164             temp->set_latitude(-temp->get_latitude());
00165             temp->set_longitude(-temp->get_longitude());
00166             break;}
00167         case Record::TYPE_MIME_VCARD:{
00168             RecordVCard *temp = (RecordVCard*)r;
00169             (*temp)[RecordVCard::NAME]="name change";
00170             (*temp)[RecordVCard::NICKNAME]="nic change";
00171             break;}
00172         case Record::TYPE_WIFI_CONF:{
00173             RecordWifiConf * temp = (RecordWifiConf*)r;
00174             temp->set_network_ssid("hackMe");
00175             temp->set_network_key("qwerty");
00176             temp->set_auth_type(RecordWifiConf::AUTH_WPA2_PSK);
00177             temp->set_encryption_type(RecordWifiConf::ENC_TYPE_AES_TKIP);
00178             break;}
00179         case Record::TYPE_UNKNOWN:{
00180             printf("Unknown record\r\n");
00181             break;}
00182     }//switch
00183 }//changeRecord
00184 
00185 
00186 /**
00187  * Class that print read a message and print it on console,
00188  * and enable the user button when it finish
00189  */
00190 class ReadMessageCallback : public NDefLib::NDefNfcTag::Callbacks{
00191 
00192     NDefLib::Message *mMsg; /// Message where read
00193     bool *mDisableButton; /// enable the user button
00194 
00195     void on_finish(const char *const msg){
00196         printf(msg);
00197         *mDisableButton=false;
00198     }
00199 
00200 public:
00201     /**
00202      *
00203      * @param disableEnable set to false when the read finish
00204      */
00205     ReadMessageCallback(bool *disableEnable):mMsg(NULL),
00206         mDisableButton(disableEnable){}
00207 
00208     /**
00209      * Create the message and ask to read it
00210      */
00211     virtual void on_session_open(NDefLib::NDefNfcTag *tag,bool success){
00212         if(!success){
00213             return on_finish("Error Opening Session\r\n");
00214         }//if
00215         mMsg = new NDefLib::Message;
00216         tag->read(mMsg);
00217     }
00218 
00219     /**
00220      * Print all the record inside the message
00221      */
00222     virtual void on_message_read(NDefLib::NDefNfcTag *tag,bool success,
00223             const NDefLib::Message *readMsg){
00224         if(!success || readMsg->get_N_records()==0){
00225             delete mMsg;
00226             return on_finish("Error Reading\r\n");
00227         }else{
00228             printf("Message Read\r\n\n");
00229             for(uint32_t i=0;i<readMsg->get_N_records();i++){
00230                 NDefLib::Record *r = (*readMsg)[i];
00231                 print_record(r);
00232                 delete r;
00233             }//for
00234             delete mMsg;
00235         }//if-else
00236         tag->close_session();
00237     }
00238 
00239     /**
00240      * Enable the button
00241      */
00242     virtual void on_session_close(NDefLib::NDefNfcTag *,bool success){
00243         if(success)
00244             on_finish("Read Session close\r\n");
00245         else
00246             on_finish("Read Session close Error\r\n");
00247     }
00248 
00249 };
00250 
00251 /**
00252  * Read the message, change some data and write it back
00253  */
00254 class ChangeMessageCallback : public NDefLib::NDefNfcTag::Callbacks{
00255 
00256     ReadMessageCallback* mReadMessage;
00257     NDefLib::Message *mMsg;
00258 
00259     /**
00260      * Change all the record in the message.
00261      * @param readMsg Message to change.
00262      */
00263     static void change_content(const NDefLib::Message *readMsg){
00264         for(uint32_t i=0;i<readMsg->get_N_records();i++){
00265             change_record((*readMsg)[i]);
00266         }//for
00267     }//changeContent
00268 
00269     /**
00270      * Delete all the record and the message.
00271      */
00272     void delete_message(){
00273         NDefLib::Message::remove_and_delete_all_record(*mMsg);
00274         delete mMsg;
00275     }//deleteMessage
00276 
00277 public:
00278 
00279     /**
00280      * @param readCallback Callback needed to print the tag content after the change
00281      */
00282     ChangeMessageCallback(ReadMessageCallback* readCallback):
00283         mReadMessage(readCallback),mMsg(NULL){}
00284 
00285     /**
00286      * Ask to read the tag content
00287      */
00288     virtual void on_session_open(NDefLib::NDefNfcTag *tag,bool success){
00289         if(!success){
00290             printf("Error Opening the session");
00291             return;
00292         }//else
00293         mMsg = new NDefLib::Message;
00294         tag->read(mMsg);
00295     }
00296 
00297     /**
00298      * Change the message content and write it back
00299      */
00300     virtual void on_message_read(NDefLib::NDefNfcTag *tag,bool success,
00301             const NDefLib::Message *readMsg){
00302         if(!success || readMsg->get_N_records()==0){
00303             printf("Error Reading\r\n");
00304             delete_message();
00305         }else{
00306             printf("Message Read: change message content\r\n");
00307             change_content(readMsg);
00308             printf("Start write new message\r\n");
00309             tag->write(*mMsg);
00310         }//if-else
00311     }
00312 
00313     /**
00314      * Delete the Message and close the session
00315      */
00316     virtual void on_message_write(NDefLib::NDefNfcTag *tag,bool success){
00317         delete_message();
00318         if(success){
00319             printf("Message Wrote\r\n");
00320             tag->close_session();
00321         }else
00322             printf("Error Writing\r\n");
00323     }//onMessageWrite
00324 
00325     /**
00326      * Set the callback for print the tag content and open a new session
00327      */
00328     virtual void on_session_close(NDefLib::NDefNfcTag *tag,bool success){
00329         if(success){
00330             printf("Change Session close\r\n");
00331             tag->set_callback(mReadMessage);
00332             tag->open_session();
00333         }else
00334             printf("Change Session close Error\r\n");
00335     }
00336 
00337 };
00338 
00339 /**
00340  * Create and write a message in a nfc tag
00341  */
00342 class WriteMessageCallback : public NDefLib::NDefNfcTag::Callbacks{
00343 
00344     ReadMessageCallback* mReadMessage;
00345     NDefLib::Message mMsg;
00346 
00347 public:
00348 
00349     /**
00350      *
00351      * @param readCallback Callbacks to use for print the tag content
00352      */
00353     WriteMessageCallback(ReadMessageCallback* readCallback):
00354         mReadMessage(readCallback){}
00355 
00356     /**
00357      *
00358      */
00359     virtual void on_session_open(NDefLib::NDefNfcTag *tag,bool success){
00360         if(!success){
00361             printf("Error Opening the Session\r\n");
00362             return;
00363         }//else
00364 
00365         printf("Session open\r\n");
00366 
00367         NDefLib::RecordAAR *rAAR = 
00368             new NDefLib::RecordAAR("com.st.BlueMS");
00369         mMsg.add_record(rAAR);
00370 
00371         NDefLib::RecordSMS *rSMS = 
00372             new NDefLib::RecordSMS("123456789","st.com.BlueMS");
00373         mMsg.add_record(rSMS);
00374 
00375         NDefLib::RecordGeo *rGeo = 
00376             new NDefLib::RecordGeo(123.123,-456.789);
00377         mMsg.add_record(rGeo);
00378 
00379         NDefLib::RecordURI *rUri = 
00380             new NDefLib::RecordURI(NDefLib::RecordURI::HTTP_WWW,"http://www.st.com");
00381         mMsg.add_record(rUri);
00382 
00383         NDefLib::RecordMail *rMail = 
00384             new NDefLib::RecordMail("mail@st.com","ciao","da nfc tag");
00385         mMsg.add_record(rMail);
00386 
00387         NDefLib::RecordMimeType *rText1 =
00388             new NDefLib::RecordMimeType("text/plain",(const uint8_t*)"Ciao",4);
00389         mMsg.add_record(rText1);
00390 
00391         NDefLib::RecordText *rText2 =
00392             new NDefLib::RecordText(NDefLib::RecordText::UTF8,"it","ciao");
00393         mMsg.add_record(rText2);
00394 
00395         NDefLib::RecordWifiConf *rWifi =
00396             new NDefLib::RecordWifiConf("OpenNetwork");
00397         mMsg.add_record(rWifi);
00398 
00399         NDefLib::RecordVCard::VCardInfo_t cardInfo;
00400         cardInfo[NDefLib::RecordVCard::FORMATTED_NAME]="prova prova1";
00401         cardInfo[NDefLib::RecordVCard::ADDRESS_HOME]=";;1 Main St.;Springfield;IL;12345;USA";
00402         cardInfo[NDefLib::RecordVCard::ADDRESS_WORK]=";;2 Main St.;Springfield;IL;12345;USA";
00403         cardInfo[NDefLib::RecordVCard::EMAIL_WORK]="workmail@st.com";
00404         cardInfo[NDefLib::RecordVCard::EMAIL_HOME]="homemail@st.com";
00405         cardInfo[NDefLib::RecordVCard::GEO]="39.95;-75.1667";
00406         cardInfo[NDefLib::RecordVCard::IMPP]="aim:johndoe@aol.com";
00407         cardInfo[NDefLib::RecordVCard::NAME]="prova2;prova3";
00408         cardInfo[NDefLib::RecordVCard::NICKNAME]="test";
00409         cardInfo[NDefLib::RecordVCard::NOTE]="A good test";
00410         cardInfo[NDefLib::RecordVCard::ORGANIZATION]="STM";
00411         cardInfo[NDefLib::RecordVCard::TEL_HOME]="123";
00412         cardInfo[NDefLib::RecordVCard::TEL_MOBILE]="456";
00413         cardInfo[NDefLib::RecordVCard::TEL_WORK]="789";
00414         cardInfo[NDefLib::RecordVCard::TITLE]="King";
00415         cardInfo[NDefLib::RecordVCard::URL]="www.st.com";
00416         cardInfo[NDefLib::RecordVCard::PHOTO_URI]="http://www.st.com/st-web-ui/static/active/en/fragment/multimedia/image/picture/customer_focus.jpg";
00417         NDefLib::RecordVCard *rVCard = new NDefLib::RecordVCard(cardInfo);
00418         mMsg.add_record(rVCard);
00419 
00420         //write it
00421         tag->write(mMsg);
00422     }
00423 
00424 
00425     /**
00426      * Close the session
00427      */
00428     virtual void on_message_write(NDefLib::NDefNfcTag *tag,bool success){
00429         NDefLib::Message::remove_and_delete_all_record(mMsg);
00430         if(!success){
00431             printf("Error Writing\r\n");
00432             return;
00433         }
00434         printf("Message wrote\r\n");
00435         tag->close_session();
00436     }
00437 
00438     /**
00439      * Set the callback to print the tag content and open a new session
00440      */
00441     virtual void on_session_close(NDefLib::NDefNfcTag *tag,bool success){
00442         if(success){
00443             printf("Write Session close\r\n");
00444             tag->set_callback(mReadMessage);
00445             tag->open_session();
00446         }else
00447             printf("Write Session close Error\r\n");
00448     }//onSessionClose
00449 
00450 };
00451 
00452 
00453 static bool buttonPress=false; /// true when the user press the message
00454 
00455 /**
00456  * Call back called when the user press the button
00457  */
00458 static void set_button_press(){
00459     buttonPress=true;
00460 }//if buttonPress
00461 
00462 static volatile bool nfcEvent=false; /// true if there is an nfc interrupt
00463 
00464 /**
00465  * Call back called when the user press the button
00466  */
00467 static void set_nfc_event(){
00468     nfcEvent=true;
00469 }//
00470 
00471 /**
00472  * Write a message and when the user press the button it read the message, change it and update it.
00473  */
00474 void sampleAsync_writeAndChangeAll() {
00475     DigitalOut nucleoLed(LED1);
00476     
00477     //instance the board with the default parameters
00478     I2C i2cChannel(XNucleoNFC01A1::DEFAULT_SDA_PIN,XNucleoNFC01A1::DEFAULT_SDL_PIN);
00479     XNucleoNFC01A1 *nfcNucleo = XNucleoNFC01A1::instance(i2cChannel,&set_nfc_event);
00480 
00481     //retrieve the Nfc component
00482     M24SR &nfc = nfcNucleo->get_M24SR();
00483     //retrieve the NdefLib interface
00484     NDefLib::NDefNfcTag& tag = nfc.get_NDef_tag();
00485 
00486     //switch on the first led    
00487     nfcNucleo->get_led1()=1;
00488     nfcNucleo->get_led2()=0;
00489     nfcNucleo->get_led3()=0;
00490 
00491     ReadMessageCallback readMessageCallback(&buttonPress);
00492     WriteMessageCallback writeBigMessageCallback(&readMessageCallback);
00493     ChangeMessageCallback changeMessageCallback(&readMessageCallback);
00494 
00495     //Enable async mode
00496     if(nfc.get_session()==M24SR::M24SR_SUCCESS)
00497         nfc.manage_I2C_GPO(M24SR::I2C_ANSWER_READY);
00498 
00499     //write the message
00500     tag.set_callback(&writeBigMessageCallback);
00501     tag.open_session();
00502 
00503     //enable the button
00504     #if defined(TARGET_STM)
00505         InterruptIn userButton(USER_BUTTON);
00506     #else
00507         InterruptIn userButton(SW2);
00508     #endif
00509     userButton.fall(set_button_press);
00510 
00511     printf("Start main loop\r\n");
00512     while(true) {
00513         if(buttonPress){
00514             buttonPress=false;
00515             shift_led(nfcNucleo->get_led1(),nfcNucleo->get_led2(),nfcNucleo->get_led3());
00516             tag.set_callback(&changeMessageCallback);
00517             tag.open_session();
00518         }else if (nfcEvent){
00519             nfcEvent=false;
00520             nucleoLed=!nucleoLed;
00521             nfcNucleo->get_M24SR().manage_event();
00522         }//if-else
00523         __WFE();
00524     }//while
00525 }