352 lines
12 KiB
Plaintext
352 lines
12 KiB
Plaintext
/* ARM assembly Raspberry PI */
|
|
/* program yahoosearch.s */
|
|
/* access RosettaCode.org and data extract */
|
|
/* use openssl for access to port 443 */
|
|
/* test openssl : package libssl-dev */
|
|
|
|
/* REMARK 1 : this program use routines in a include file
|
|
see task Include a file language arm assembly
|
|
for the routine affichageMess conversion10
|
|
see at end of this program the instruction include */
|
|
|
|
/*******************************************/
|
|
/* Constantes */
|
|
/*******************************************/
|
|
.equ STDOUT, 1 @ Linux output console
|
|
.equ EXIT, 1 @ Linux syscall
|
|
.equ WRITE, 4 @ Linux syscall
|
|
.equ BRK, 0x2d @ Linux syscall
|
|
.equ CHARPOS, '@'
|
|
|
|
.equ EXIT, 1
|
|
.equ TAILLEBUFFER, 500
|
|
|
|
.equ SSL_OP_NO_SSLv3, 0x02000000
|
|
.equ SSL_OP_NO_COMPRESSION, 0x00020000
|
|
.equ SSL_MODE_AUTO_RETRY, 0x00000004
|
|
.equ SSL_CTRL_MODE, 33
|
|
|
|
.equ BIO_C_SET_CONNECT, 100
|
|
.equ BIO_C_DO_STATE_MACHINE, 101
|
|
.equ BIO_C_SET_SSL, 109
|
|
.equ BIO_C_GET_SSL, 110
|
|
|
|
.equ LGBUFFERREQ, 512001
|
|
.equ LGBUFFER2, 128001
|
|
|
|
/*********************************/
|
|
/* Initialized data */
|
|
/*********************************/
|
|
.data
|
|
szMessDebutPgm: .asciz "Début du programme. \n"
|
|
szRetourLigne: .asciz "\n"
|
|
szMessFinOK: .asciz "Fin normale du programme. \n"
|
|
szMessErreur: .asciz "Erreur !!!"
|
|
szMessExtractArea: .asciz "Extraction = "
|
|
szNomSite1: .asciz "search.yahoo.com:443" @ host name and port
|
|
szLibStart: .asciz ">Rosetta Code" @ search string
|
|
szNomrepCertif: .asciz "/pi/certificats"
|
|
szRequete1: .asciz "GET /search?p=\"Rosettacode.org\"&b=1 HTTP/1.1 \r\nHost: search.yahoo.com\r\nConnection: keep-alive\r\nContent-Type: text/plain\r\n\r\n"
|
|
/*********************************/
|
|
/* UnInitialized data */
|
|
/*********************************/
|
|
.bss
|
|
.align 4
|
|
sBufferreq: .skip LGBUFFERREQ
|
|
szExtractArea: .skip TAILLEBUFFER
|
|
stNewSSL: .skip 200
|
|
/*********************************/
|
|
/* code section */
|
|
/*********************************/
|
|
.text
|
|
.global main
|
|
main:
|
|
ldr r0,iAdrszMessDebutPgm
|
|
bl affichageMess @ start message
|
|
|
|
/* connexion host port 443 and send query */
|
|
bl envoiRequete
|
|
cmp r0,#-1
|
|
beq 99f @ error ?
|
|
|
|
bl analyseReponse
|
|
|
|
ldr r0,iAdrszMessFinOK @ end message
|
|
bl affichageMess
|
|
mov r0, #0 @ return code ok
|
|
b 100f
|
|
99:
|
|
ldr r0,iAdrszMessErreur @ error
|
|
bl affichageMess
|
|
mov r0, #1 @ return code error
|
|
b 100f
|
|
100:
|
|
mov r7,#EXIT @ program end
|
|
svc #0 @ system call
|
|
iAdrszMessDebutPgm: .int szMessDebutPgm
|
|
iAdrszMessFinOK: .int szMessFinOK
|
|
iAdrszMessErreur: .int szMessErreur
|
|
|
|
/*********************************************************/
|
|
/* connexion host port 443 and send query */
|
|
/*********************************************************/
|
|
envoiRequete:
|
|
push {r2-r8,lr} @ save registers
|
|
@*************************************
|
|
@ openSsl functions use *
|
|
@*************************************
|
|
@init ssl
|
|
bl OPENSSL_init_crypto
|
|
bl ERR_load_BIO_strings
|
|
mov r2, #0
|
|
mov r1, #0
|
|
mov r0, #2
|
|
bl OPENSSL_init_crypto
|
|
mov r2, #0
|
|
mov r1, #0
|
|
mov r0, #0
|
|
bl OPENSSL_init_ssl
|
|
cmp r0,#0
|
|
blt erreur
|
|
bl TLS_client_method
|
|
bl SSL_CTX_new
|
|
cmp r0,#0
|
|
ble erreur
|
|
mov r6,r0 @ save ctx
|
|
ldr r1,iFlag
|
|
bl SSL_CTX_set_options
|
|
mov r0,r6
|
|
mov r1,#0
|
|
ldr r2,iAdrszNomrepCertif
|
|
bl SSL_CTX_load_verify_locations
|
|
cmp r0,#0
|
|
ble erreur
|
|
mov r0,r6
|
|
bl BIO_new_ssl_connect
|
|
cmp r0,#0
|
|
ble erreur
|
|
mov r5,r0 @ save bio
|
|
mov r1,#BIO_C_GET_SSL
|
|
mov r2,#0
|
|
ldr r3,iAdrstNewSSL
|
|
bl BIO_ctrl
|
|
ldr r0,iAdrstNewSSL
|
|
ldr r0,[r0]
|
|
mov r1,#SSL_CTRL_MODE
|
|
mov r2,#SSL_MODE_AUTO_RETRY
|
|
mov r3,#0
|
|
bl SSL_ctrl
|
|
mov r0,r5 @ bio
|
|
mov r1,#BIO_C_SET_CONNECT
|
|
mov r2,#0
|
|
ldr r3,iAdrszNomSite1
|
|
bl BIO_ctrl
|
|
mov r0,r5 @ bio
|
|
mov r1,#BIO_C_DO_STATE_MACHINE
|
|
mov r2,#0
|
|
mov r3,#0
|
|
bl BIO_ctrl
|
|
@ compute query length
|
|
mov r2,#0
|
|
ldr r1,iAdrszRequete1 @ query
|
|
1:
|
|
ldrb r0,[r1,r2]
|
|
cmp r0,#0
|
|
addne r2,#1
|
|
bne 1b
|
|
@ send query
|
|
mov r0,r5 @ bio
|
|
@ r1 = address query
|
|
@ r2 = length query
|
|
mov r3,#0
|
|
bl BIO_write @ send query
|
|
cmp r0,#0
|
|
blt erreur
|
|
ldr r7,iAdrsBufferreq @ buffer address
|
|
2: @ begin loop to read datas
|
|
mov r0,r5 @ bio
|
|
mov r1,r7 @ buffer address
|
|
mov r2,#LGBUFFERREQ - 1
|
|
mov r3,#0
|
|
bl BIO_read
|
|
cmp r0,#0
|
|
ble 4f @ error ou pb server
|
|
add r7,r0
|
|
sub r2,r7,#6
|
|
ldr r2,[r2]
|
|
ldr r3,iCharEnd
|
|
cmp r2,r3 @ text end ?
|
|
beq 4f
|
|
mov r1,#0xFFFFFF @ delay loop
|
|
3:
|
|
subs r1,#1
|
|
bgt 3b
|
|
b 2b @ loop read other chunk
|
|
4: @ read end
|
|
//ldr r0,iAdrsBufferreq @ to display buffer response of the query
|
|
//bl affichageMess
|
|
mov r0, r5 @ close bio
|
|
bl BIO_free_all
|
|
mov r0,#0
|
|
b 100f
|
|
erreur: @ error display
|
|
ldr r1,iAdrszMessErreur
|
|
bl afficheerreur
|
|
mov r0,#-1 @ error code
|
|
b 100f
|
|
100:
|
|
pop {r2-r8,lr} @ restaur registers
|
|
bx lr
|
|
iAdrszRequete1: .int szRequete1
|
|
iAdrsBufferreq: .int sBufferreq
|
|
iFlag: .int SSL_OP_NO_SSLv3 | SSL_OP_NO_COMPRESSION
|
|
iAdrstNewSSL: .int stNewSSL
|
|
iAdrszNomSite1: .int szNomSite1
|
|
iAdrszNomrepCertif: .int szNomrepCertif
|
|
iCharEnd: .int 0x0A0D300A
|
|
/*********************************************************/
|
|
/* response analyze */
|
|
/*********************************************************/
|
|
analyseReponse:
|
|
push {r1-r4,lr} @ save registers
|
|
ldr r0,iAdrsBufferreq @ buffer address
|
|
ldr r1,iAdrszLibStart @ key text address
|
|
mov r2,#2 @ occurence key text
|
|
mov r3,#-11 @ offset
|
|
ldr r4,iAdrszExtractArea @ address result area
|
|
bl extChaine
|
|
cmp r0,#-1
|
|
beq 99f
|
|
ldr r0,iAdrszMessExtractArea
|
|
bl affichageMess
|
|
ldr r0,iAdrszExtractArea @ résult display
|
|
bl affichageMess
|
|
ldr r0,iAdrszRetourLigne
|
|
bl affichageMess
|
|
b 100f
|
|
99:
|
|
ldr r0,iAdrszMessErreur @ error
|
|
bl affichageMess
|
|
mov r0, #-1 @ error return code
|
|
b 100f
|
|
100:
|
|
pop {r1-r4,lr} @ restaur registers
|
|
bx lr
|
|
iAdrszLibStart: .int szLibStart
|
|
iAdrszExtractArea: .int szExtractArea
|
|
iAdrszMessExtractArea: .int szMessExtractArea
|
|
iAdrszRetourLigne: .int szRetourLigne
|
|
/*********************************************************/
|
|
/* Text Extraction behind text key */
|
|
/*********************************************************/
|
|
/* r0 buffer address */
|
|
/* r1 key text to search */
|
|
/* r2 number occurences to key text */
|
|
/* r3 offset */
|
|
/* r4 result address */
|
|
extChaine:
|
|
push {r2-r8,lr} @ save registers
|
|
mov r5,r0 @ save buffer address
|
|
mov r6,r1 @ save key text
|
|
@ compute text length
|
|
mov r7,#0
|
|
1: @ loop
|
|
ldrb r0,[r5,r7] @ load a byte
|
|
cmp r0,#0 @ end ?
|
|
addne r7,#1 @ no -> loop
|
|
bne 1b
|
|
add r7,r5 @ compute text end
|
|
|
|
mov r8,#0
|
|
2: @ compute length text key
|
|
ldrb r0,[r6,r8]
|
|
cmp r0,#0
|
|
addne r8,#1
|
|
bne 2b
|
|
|
|
3: @ loop to search nième(r2) key text
|
|
mov r0,r5
|
|
mov r1,r6
|
|
bl rechercheSousChaine
|
|
cmp r0,#0
|
|
blt 100f
|
|
subs r2,#1
|
|
addgt r5,r0
|
|
addgt r5,r8
|
|
bgt 3b
|
|
add r0,r5 @ add address text to index
|
|
add r3,r0 @ add offset
|
|
sub r3,#1
|
|
@ and add length key text
|
|
add r3,r8
|
|
cmp r3,r7 @ > at text end
|
|
movge r0,#-1 @ yes -> error
|
|
bge 100f
|
|
mov r0,#0
|
|
4: @ character loop copy
|
|
ldrb r2,[r3,r0]
|
|
strb r2,[r4,r0]
|
|
cmp r2,#0 @ text end ?
|
|
moveq r0,#0 @ return zero
|
|
beq 100f
|
|
cmp r0,#48 @ extraction length
|
|
beq 5f
|
|
add r0,#1
|
|
b 4b @ and loop
|
|
5:
|
|
mov r2,#0 @ store final zéro
|
|
strb r2,[r4,r0]
|
|
add r0,#1
|
|
add r0,r3 @ r0 return the last position of extraction
|
|
@ it is possible o search another text
|
|
100:
|
|
pop {r2-r8,lr} @ restaur registers
|
|
bx lr
|
|
|
|
/******************************************************************/
|
|
/* search substring in string */
|
|
/******************************************************************/
|
|
/* r0 contains address string */
|
|
/* r1 contains address substring */
|
|
/* r0 return start index substring or -1 if not find */
|
|
rechercheSousChaine:
|
|
push {r1-r6,lr} @ save registers
|
|
mov r2,#0 @ index position string
|
|
mov r3,#0 @ index position substring
|
|
mov r6,#-1 @ search index
|
|
ldrb r4,[r1,r3] @ load first byte substring
|
|
cmp r4,#0 @ zero final ?
|
|
moveq r0,#-1 @ error
|
|
beq 100f
|
|
1:
|
|
ldrb r5,[r0,r2] @ load string byte
|
|
cmp r5,#0 @ zero final ?
|
|
moveq r0,#-1 @ yes -> not find
|
|
beq 100f
|
|
cmp r5,r4 @ compare character two strings
|
|
beq 2f
|
|
mov r6,#-1 @ not equal - > raz index
|
|
mov r3,#0 @ and raz byte counter
|
|
ldrb r4,[r1,r3] @ and load byte
|
|
add r2,#1 @ and increment byte counter
|
|
b 1b @ and loop
|
|
2: @ characters equal
|
|
cmp r6,#-1 @ first character equal ?
|
|
moveq r6,r2 @ yes -> start index in r6
|
|
add r3,#1 @ increment substring counter
|
|
ldrb r4,[r1,r3] @ and load next byte
|
|
cmp r4,#0 @ zero final ?
|
|
beq 3f @ yes -> search end
|
|
add r2,#1 @ else increment string index
|
|
b 1b @ and loop
|
|
3:
|
|
mov r0,r6 @ return start index substring in the string
|
|
100:
|
|
pop {r1-r6,lr} @ restaur registres
|
|
bx lr
|
|
|
|
/***************************************************/
|
|
/* ROUTINES INCLUDE */
|
|
/***************************************************/
|
|
.include "../affichage.inc"
|